https://kotlinlang.org logo
#compose
Title
# compose
s

Simon Stahl

01/26/2022, 7:48 PM
Anyone knows if there is something in the works to support previews with viewmodels?
t

Thiago

01/26/2022, 7:52 PM
Your compositions should have ViewModel as parameters and you can replace it with Fakes. Previews should be fast as it can. Using real implementations can turn Preview as slow as it is.
c

curioustechizen

01/26/2022, 8:10 PM
There is indeed a merged commit but I don't know when it will land in AS. Honestly I would think twice before using this feature. https://android-review.googlesource.com/c/platform/frameworks/support/+/1827754
s

Simon Stahl

01/26/2022, 8:23 PM
I see. Yes sure, had to be careful that the VM does not access any outside resources. Passing fakes kind of sucks. Faking a bunch of resources, flows, states etc can become a mess quickly. Also if you have a tree of composables and each use its own VM, then you cannot pass them down and can only have previews for the lowest down nodes
c

curioustechizen

01/26/2022, 9:37 PM
True. I wish there was a way to "compose" ViewModels (not in the Jetpack Compose sense of the word). I've stuck to having only the top level Composable know anything about ViewModels but sometimes this makes these ViewModels pretty large.
s

Simon Stahl

01/26/2022, 10:12 PM
Agree. Well it sounds like this is the only solution for now 😞
t

Thiago

01/27/2022, 1:58 PM
Well, if we'll need decouple things, we'll end up with 2 compositions: 1 to Data and another to UI. Ex:
Copy code
@Composable fun justForData(externalVM: ViewModel) {
    val internalVM = ...
    StatelessComposable(each data that we get from VM)
}

@Preview fun preview() {
    StatelessComposable(each fake data that we need to preview)
}
And if you have DI in your code, you don't need pass VMs by Composable parameters. I think that it's better than turns AS and Preview more heavy just to instantiate VMs.
s

Simon Stahl

01/27/2022, 5:22 PM
Yes that is actually what we are currently doing. Like stated above, the issue is when you have composables that contain other composables with their own VMs. The only solution that we found for that so far is to add callbacks to create those and keep the preview-able composable stateless . It works but makes the code much harder to read and understand
Copy code
@Composable fun justForData(externalVM: ViewModel) {
    val internalVM = ...
    StatelessComposable(externalVM.someData, createChild1 = { ChildComposble1(viewModel()) }, createChild2 = { ChildComposble2(viewModel()) })
}
🦜 1