0

My code is something like this:

class ViewModel: ObservableObject {
   @Published var value = ""
}

struct ContentView: View {
   @StateObject var viewModel = ViewModel()
   var body: some View {
            Group {
                if viewModel.userSession != nil {
                    MyTabView()
                } else {
                    LoginView()
                }
            }
            .environmentObject(viewModel)
   }
}

struct MyTabView: View {
   var body: some View {
            TabView {
                 View1()
                    .tabItem{}
                 View2()
                    .tabItem{}
                 View3()
                    .tabItem{}
                 View4()
                    .tabItem{}
            }
   }
}

struct View4: View {
   @EnvironmentObject var viewModel: ViewModel
   var body: some View {
            NavigationView {
                NavigationLink(destination: EditView().environmentObject(viewModel)){
                    Text("Edit")
                }
            }
   }
}

struct EditView: View {
   @EnvironmentObject var viewModel: ViewModel
   var body: some View {
            if viewModel.value != "" {        //this is where I get the error
                Text("\(viewModel.value)")
            }
   }
}

I've tried putting the environmentObject at MyTabView() in ContentView()

struct ContentView: View {
   @StateObject var viewModel = ViewModel()
   var body: some View {
            Group {
                if viewModel.userSession != nil {
                    MyTabView().environmentObject(viewModel)
                } else {
                    LoginView()
                }
            }
   }
}

I've tried putting the environmentObject at NavigationView in View4()

struct View4: View {
   @EnvironmentObject var viewModel: ViewModel
   var body: some View {
            NavigationView {
                NavigationLink(destination: EditView()){
                    Text("Edit")
                }
            }.environmentObject(viewModel)
   }
}

The value from ViewModel is not getting passed into the EditView. I have tried many solutions I can find but non of those are helping with the error. Can anyone please let me know what have I done wrong?

Ernest Tan
  • 11
  • 4
  • I think it should work fine. I think your error is coming from trying to call `print()` and not returning `some View` correctly. Try replacing the `print("\(viewModel.value)")` with `Text("\(viewModel.value)")` – aciniglio Jun 13 '22 at 19:16
  • @aciniglio I just tried, the error is still there. Thanks anyway. – Ernest Tan Jun 13 '22 at 19:40
  • is the code you are showing us, really is the code giving you the error? Is is very strange that you have `if viewModel.userSession != nil {...}`, when `ViewModel` does not have a `userSession`. – workingdog support Ukraine Jun 14 '22 at 00:21
  • 1
    please read this info on how to ask a question on SO, https://stackoverflow.com/help/how-to-ask especially the part on `Help others reproduce the problem` – workingdog support Ukraine Jun 14 '22 at 00:52
  • @workingdogsupportUkraine the code I gave here is just the simplified version of my code. The viewModel.userSession `@Published var userSession: FirebaseAuth.User?` is used to detect user login which initialized in ViewModel `override init() { super.init() userSession = Auth.auth().currentUser }` – Ernest Tan Jun 14 '22 at 07:13

1 Answers1

1

Here is the test code I used (entirely based on yours) that shows "...The value from ViewModel is getting passed into the EditView...". Unless I missed something, the code you provide does not reproduce the error you show.

class ViewModel: ObservableObject {
    @Published var value = ""
    @Published var userSession: String? // <-- for testing
}

struct ContentView: View {
    @StateObject var viewModel = ViewModel()
    var body: some View {
        Group {
            if viewModel.userSession != nil {
                MyTabView()
            } else {
                LoginView()
            }
        }.environmentObject(viewModel)
    }
}

struct MyTabView: View {
    var body: some View {
        TabView {
            Text("View1").tabItem{Text("View1")}
            Text("View2").tabItem{Text("View2")}
            Text("View3").tabItem{Text("View3")}
            View4().tabItem{Text("View4")}
        }
    }
}

struct View4: View {
    @EnvironmentObject var viewModel: ViewModel
    var body: some View {
        NavigationView {
            NavigationLink(destination: EditView().environmentObject(viewModel)){
                Text("Edit")
            }
        }
    }
}

struct EditView: View {
    @EnvironmentObject var viewModel: ViewModel
    var body: some View {
        if viewModel.value != "" {  // <-- here no error
            Text(viewModel.value) // <-- here viewModel.value is a String
        }
    }
}

struct LoginView: View {
    @EnvironmentObject var viewModel: ViewModel
    var body: some View {
        Button("Click me", action: {
            viewModel.userSession = "something"  // <-- to trigger the if in ContentView
            viewModel.value = "testing-4-5-6"  // <-- here change the value
        })
    }
}

Try this code and let us know if you get the error you show.