Noticed that previews do not work when I use a vie...
# compose
j
Noticed that previews do not work when I use a viewModel in a composable. How do you get around this?
b
I’m generally creating two composables- one that uses the view model (either as a parameter or via the
viewModels()
extension function) and one that only takes in the state I need. E.g.:
Copy code
@Composable
fun AccountScreen(
  viewModel: AccountViewModel
) {
  AccountScreen(viewModel.screenState)
}

@Composable
private fun AccountScreen(
  state: AccountScreenState
) {
  // ...
}

// Now you can actually write a preview
@Preview
@Composable
private fun LoggedInAccountPreview() {
  AccountScreen(AccountScreenState.LoggedIn)
}
i
b
preview the one taking in state and populate it with dummy data, as mentioned
j
What if the composable takes in a viewmodel to make a call like viewModel.login()
b
hoist that up back to the parent composable via a lambda
actioner: (Event) -> Unit
j
Now you are talking.
So practically there is no way to preview a screen with many composables if I'm using the viewModel?
i
j
Yeah @Ian Lake When I pass it in as a parameter, and include a default value for the ViewModel that pulls from Koin, the composable does not display. I get the message Koin cannot be initialized.
i
The whole point of passing it in is so that your preview code can override the default value and provide a proper test/fake for your preview to use
j
Okay. How do I provide a test/fake for a ViewModel
i
What does your preview need to function? You might look at any of the many mocking libraries out there or you might want to just call your ViewModel's constructor directly, passing in mocks for any other dependencies it has. If you're unfamiliar with the terms mocks and fakes, there are quite a few blog posts out there
1
j
Thanks. I'll try a mocking library.