Initializing a @StateObject from an @EnvironmentObject

I have an @EnvironmentObject, store, I need to pass the variable as a parameter to my @StateObject's, vm, initializer. I first tried the View's init but an @EnvironmentObject is not yet existing upon View init. So then I tried the onAppear but onAppear does not allow use of self. Is this even possible? For reference I've included both the init and the onAppear, neither works.

Code Block struct NewsView: View {
  @EnvironmentObject var store: Store
  @StateObject private var vm: NewsViewModel
   
  init() {
    self._vm = StateObject(wrappedValue: NewsViewModel(self._store.wrappedValue.newsApi))
  }
       
  var body: some View {
    if vm.show == true {
      HStack {
        Image("round-flag")
          .resizable()
          .aspectRatio(contentMode: .fit)
          .frame(width: 20)
          .rotationEffect(.degrees(-28))
         
        Text(self.vm.news?.subject ?? "")
          .instaStylePrimary()
         
        Button {
          vm.show = false
        } label: {
          Image(systemName: "xmark")
            .instaStylePrimary()
            .frame(width: 12)
            .foregroundColor(.gray)
        }
      }
    }
  }
}


Is this even possible?

As far as I know, the answer currently seems to be NO.

You may need to go back to the place where your EnvironmentObject is instantiated, and add another function to instantiate the StateObject.

So what's the solution for using MVVM in a setup where you're using EnvironmentObject to pass in access to the model?

I'm thinking of something like Core Data where you can use an EnvironmentObject to pass in an NSManagedObjectContext. You can't create an @EnvironmentObject ViewModel in init because the EnvironmentObject isn't set yet. And the EnvironmentObject property's didSet doesn't fire so you can't do it there.

Creating the ViewModel in onAppear works but seems a bit clumsy. Is that the best way to do this?

Yes, this seems clumsy at the moment. As noted, the environmentObject is not available in init.

It is possible to assign a temporary value on declaration:

@State private var vm: NewsViewModel = /// some temporary value

...then assign the true value in onAppear:

.onAppear {
	vm = /// it's true value, which can reference the environmentObject
}

It's not pretty, but it works.

Initializing a @StateObject from an @EnvironmentObject
 
 
Q