'SwiftUI List not updating after deleting row from Sqlite DB

I have a list of objects that a user can click on to navigate to a detailed view and then delete. This works fine but when I added a .swipeActions() to the cardListRow I get an index out of bounds error after deleting.

Initial View:

struct ContentView: View {

    //variables for Ingredient list:
    @State var ingredients: [Ingredient] = []

    var body: some View {
        NavigationView{
            ScrollView{
                VStack{
                    //Ingredient Section
                    VStack{

                        List{
                            ForEach(self.$ingredients, id: \.id){ ingredientModel in
                                //print each ingredient
                                CardListRow(item: ingredientModel)
                                    .listRowSeparator(.hidden)
                            }
                        }
                        .frame(height: 180)
                        .listStyle(.plain)
                        .onAppear(perform: {
                            print("Load ingredients from DB")
                            self.ingredients = Ingredient_DB().getIngredients()
                        })
                    }
               }
          }
     }
}

CardListRow:

struct CardListRow: View {
    @Binding var item: Ingredient
    @State var inStock: Bool = false
    @State var showingAlert: Bool = false
    
    var body: some View {
        ZStack {
            Color.white
                .cornerRadius(12)
            IngredientListItem(ingredient: $item)
        }
        .fixedSize(horizontal: false, vertical: true)
        .shadow(color: Color.black.opacity(0.2), radius: 3, x: 0, y: 2)
        .swipeActions() {
            if self.inStock == true {
                Button (action: {
                    self.inStock = false
                    item.inStock = self.inStock
                    Ingredient_DB().updateIngredient(idValue: self.item.id.uuidString, nameValue: self.item.name, inStockValue: self.item.inStock)
                }) {
                    Text("Out of stock")
                }
                .tint(.yellow)
            }else{
                Button (action: {
                    self.inStock = true
                    item.inStock = self.inStock
                    Ingredient_DB().updateIngredient(idValue: self.self.item.id.uuidString, nameValue: self.item.name, inStockValue: self.item.inStock)
                }) {
                    Text("In stock")
                }
                .tint(.green)
            }
        }
        .onAppear(perform: {
            self.inStock = item.inStock //Error occurs here. List isn't reloaded but item is out of index
        })
    }
}

IngredientListItem:

struct IngredientListItem: View {
    //ingredient to display
    @Binding var ingredient: Ingredient
    //to see if ingredient was clicked on
    @State var ingredientSelected: Bool = false
    
    var body: some View {
        //navigation link to view ingredient info
        NavigationLink (destination: ViewIngredientView(ingredient: $ingredient), isActive: self.$ingredientSelected){
            EmptyView()
        }
        HStack {
            if !ingredient.inStock{
                Image(systemName: "x.square")
                    .foregroundColor(.red)
                    .padding(.leading, 5)
            }
            Text(ingredient.name)
                .font(.body)
                .padding(.leading, 5)
                .frame(minWidth: 100)
            Divider()
                .frame(width: 10)
            Spacer()
        }
        .padding(.top, 3)
        .padding(.bottom, 3)
    }
}

ViewIngredientView:

struct ViewIngredientView: View {
    //Name of recipe received from previous view
    @Binding var ingredient: Ingredient
    
    //To return to previous view
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>
    var body: some View {
        VStack {
            Text(ingredient.name)
                .font(.title)
                .padding(.leading, 5)
        }
        .navigationBarItems(trailing:
                                HStack{
            Spacer()
            //Delete Button
            Button("Delete") {
//Remove recipe from Recipe_DB
                        Ingredient_DB().deleteIngredient(ingredientID: ingredient.id.uuidString)
                        //Remove recipe from Recipe_Ingredient_DB
                        Recipe_Ingredient_DB().deleteIngredient(ingredientIDValue: ingredient.id.uuidString)
                        //return to previous screen
                        self.mode.wrappedValue.dismiss()
            }
            .padding()
        })
    }
}

Ingredient:

import Foundation

class Ingredient: Identifiable, Hashable{
    static func == (lhs: Ingredient, rhs: Ingredient) -> Bool {
        if (lhs.id == rhs.id) {return true}
        else {return false}
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
    public var id = UUID()
    public var name: String = ""
    public var inStock: Bool = false
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source