0

The following is a project I created to demonstrate my problem. Whenever I click and view a navigation link from the Content View and then delete it from Content View, the app crashes with the error, "Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value" on line 5 in my Child View.

My Content View:

struct ContentView: View {
    @ObservedObject var ingredientViewModel = IngredientViewModel()
    private func deleteIngredient(with indexSet:IndexSet) {
        ingredientViewModel.ingredients.remove(atOffsets: indexSet)
    }
    var body: some View {
        NavigationView {
            List {
                ForEach(ingredientViewModel.ingredients) { ingredient in
                    NavigationLink(destination: IngreidentView(ingredientId: ingredient.id).environmentObject(ingredientViewModel)) {
                        Text(ingredient.name)
                    }
                }.onDelete(perform: deleteIngredient)
            }
        }
        
    }
}

My View Model:

class IngredientViewModel: ObservableObject {
    @Published
    var ingredients: [Ingredient] = [Ingredient(name: "Orange", amount: 5),Ingredient(name: "Potato", amount: 3),Ingredient(name: "Tomato",amount: 1),Ingredient(name: "Salt",amount: 2)]
}

My Ingredient Model:

struct Ingredient: Identifiable {
    var name: String
    var amount: Int
    var id = UUID().uuidString
}

My Child View in the Navigation Link

struct IngreidentView: View {
    @EnvironmentObject var db: IngredientViewModel
    var ingredientId: String
    private var ingredient: Ingredient {
        db.ingredients.filter {$0.id == ingredientId}.first!
    }
    var body: some View {
        if(ingredient.amount == 0) {
            Text("0 amount!")
        } else {
            Text("\(ingredient.amount) amount")
        }
    }
}

I used a computed property to get the ingredient in my Child View since I anticipate the ingredient will change, and I want it to be updated from the database.

  • 1
    The error is coming from the `!` on that line. This means the `ingredients.filter...` expression returns no results. You need to hide your IngredientView (which btw is misspelled) when deleting the ingredient, or make it work when it matches no ingredients. – jtbandes Dec 31 '21 at 02:38
  • I understand that the computed property will return nil if the ingredient does not exist. My question is why the computed property is even being computed in the child view when you press delete in the content view. – stack4561 Dec 31 '21 at 03:39
  • May because set is not ordered and deleting and refresh are then not compatible. That is just a supposition. But as spotted by @jtbandes , it should be better to not unwrap .first and use ?? just in case. After you could analyzed what is happening to your ingredients when deleting one. – Ptit Xav Jan 01 '22 at 10:29

0 Answers0