Hi guys, what is the best way to share a view mode...
# compose
y
Hi guys, what is the best way to share a view model between screens? I use navigation api for collecting data from multiple sign up forms. Should I use a single viewmodel for collecting the data or pass one when navigating from one form to another until I collect all the user input data?
a
Use a repository that outlives the view model lifecycle
c
I use a single shared VM for login. lemme look up how i do it. im pretty sure you gotta use compose-nav in order to do it.
So I have something like this
Copy code
@Composable
fun SignUpScreen(
    sharedViewModel: LoggedOutScreensSharedViewModel,
    viewModel: SignUpScreenViewModel = hiltViewModel(),
)
and
Copy code
@Composable
fun LoginScreen(
    sharedViewModel: LoggedOutScreensSharedViewModel,
    viewModel: LoginScreenViewModel = hiltViewModel(),
)
and
Copy code
fun NavGraphBuilder.loginGraph(navController: NavController, activity: Activity?) {
  navigation(startDestination = Screen.SignUp.route, route = Screen.LoggedOutScreens.route) {
    composable(Screen.SignUp.route) {
      val sharedVM = remember() { navController.getBackStackEntry(Screen.LoggedOutScreens.route) }

      SignUpScreen(
        sharedViewModel = hiltViewModel(sharedVM)
      )
    }
    composable(Screen.Login.route) {
      val shared = remember() { navController.getBackStackEntry(Screen.LoggedOutScreens.route) }
      LoginScreen(sharedViewModel = hiltViewModel(shared))
    }
  }
}
Seems to work fine
y
I'm working with navigation api. I use the backstackentry as the view model store owner so I can pass is to the next composable string. I can use the vm in this composable but when I try to pass it to another composable for building the form it crashes.
m
Honestly, you just have to decide what scope you want the viewmodel to be in. There's nothing wrong with this:
Copy code
val viewModel = viewModel(.....)
val navController = rememberNavController()
NavHost(...) {
}
The view model would effectively be scoped to the composable that owns the navcontroller as well, so it could be shared across the screens in your nav graph. Personally, i prefer to do this sort of thing using the activity as the ViewModelStoreOwner instead of any particular composable. This allows the view model to survive rotation and configuration changes. It's not entirely clear to me if a viewModel like above would give that to you.
I tend to use composable level view models only for individual screens (usually with rememberSaveable) with state related only to that particular screen.