0

//environment object class

class AppData: ObservableObject {
    @Published var studs : [StudentModel]   
}

    var body: some View {
        
            VStack{
                List(appData.studs,id:\.rollNo){ s in  //causing error
                    Text("\(s.rollNo)")
                    NavigationLink("", destination: StudentView(s: s))
                }
            }.navigationBarItems(trailing:
                                    Button(action: {
                                        self.addStud.toggle()
                                        
                                    }){
                                        Image(systemName: "plus")
                                            .renderingMode(.original)
                                    }
                .sheet(isPresented: $addStud, content: {
                    AddStudent()
                })
            )
            .navigationBarTitle(Text("Students"),displayMode: .inline)
    }

Fatal error: No ObservableObject of type AppData found. A View.environmentObject(_:) for AppData may be missing as an ancestor of this view.

Sidhan_T
  • 3
  • 1

1 Answers1

0

Your sample code is missing some lines at the start of the view. By the sounds of the error message, you already have something like:

struct MyView: View {
  @EnvironmentObject var appData: AppData
  // ...rest of view ...
}

Alongside that code to get a reference for your object out of the environment, you also need to ensure that, somewhere further up the chain, it's put in. Your error message is telling you that that is where the problem lies – it's looking in the environment for a type of AppData object, but there's nothing in there.

Let's say you declare it the app level; it might look something like this:

@main
struct TestDemoApp: App {
    // 1. Instantiate the object, using `@StateObejct` to make sure it's "owned" by the view
    @StateObject var appData = AppData()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(appData) // 2. make it available to the hierarchy of views
        }
    }
}

What you'll also have to do is make sure that any views that use your environment object also have access to one in their Xcode previews. You might want to create a version of AppData that has example data inside so that your previews don't mess with live data.

extension AppData {
  static var preview: AppData = ...
}

struct MyView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
      .environmentObject(AppData.preview)
  }
}
ScottM
  • 7,108
  • 1
  • 25
  • 42