2

I have a view called FormView which has its own VM called FormViewModel. In this VM I have a method which adds a dictionary to Firestore. Alongside with some variables coming from the View, so from the user input, I need to add to Firestore also some User specific details like its uid and other properties which I have stored in the SessionStore.

I'm doing this by passing to the add() method of my VM the actual session. Is it ok to pass an EnvironmentObject to a ViewModel or should I just pass only my User model stored inside SessionStore?

Which is the best approach to achieve smth like this? I have several similar scenarios in which my VM need properties stored in the User model or even in SessionStore (some computed properties)

struct FormView: View {
    @EnvironmentObject var sessionStore: SessionStore
    @ObservedObject var formViewModel = FormViewModel()

    @State var favoriteMovie: String = ""
    @State var favoriteTvShow: String = ""

    var body: some View {
        Button("add") {
            self.formViewModel.add(sessionStore: sessionStore, favoriteMovie: favoriteMovie, favoriteTvShow: favoriteTvShow)
        }
    }
}

class FormViewModel: ObservableObject {
    func add(sessionStore: sessionStore, favoriteMovie: String, favoriteTvShow: String) {
        let details: [String: Any] = [
            "ownerID": sessionStore.user.uid,
            // other stuff from sessionStore here
            "favoriteMovie": favoriteMovie,
            "favoriteTvShow": favoriteTvShow
        ]

        firestoreService.addDocument(details)
    }
}

class SessionStore: ObservableObject {
    var handle: AuthStateDidChangeListenerHandle?

    @Published var user: User?

    func listen() {
        handle = Auth.auth().addStateDidChangeListener({ (auth, user) in
            self.user = user
        })
    }
}
M1X
  • 4,971
  • 10
  • 61
  • 123
  • 1
    In my preference, i prefer to put a kind of data store within viewmodels. Therefore, I think you can 1) let the viewmodel have a data store like SessionStore and handle it with its own manipulation methods or 2) pass any data models from SessionStore to the viewmodel by the view. I would put SessionStore into the viewmodel as a property and the view would be able to use it through the viewmodel. In this case, the store doesn't need to be EnvironmentObject anymore. – Kyokook Hwang Jun 18 '20 at 01:29
  • Can you elaborate on this further? I'm running into this same issue and I don't quite follow you. In my case, I have an environment object that stores a published user property. I then have a create account view, with a create account view model. I'd like to have the view model have a function to send the request to the server, and upon success, assign the returned user to the environment objects user property. However, I can't seem to get the view model to have a reference to the environment object. – user3565259 Jul 24 '20 at 14:34

0 Answers0