What if my view model requires some info from a pa...
# compose
r
What if my view model requires some info from a parent view model? E.g. I've got a device connected, and I wanna modify some parts of it, how would I forward the connection handler from the parent VM to the child VM?
s
Can this information live higher up in some place where both VMs can look into instead?
r
Could also work. Each device got an ID associated with it.
c
The simple solution is to have the ParentVM expose a StateFlow that the ChildVM consumes, as well as a way for the ChildVM to send updates back up to the ParentVM. However, in my experience, this pattern makes for a complex UI layer and isn’t necessarily the best way to handle it. I’d recommend pushing that shared state back into a deeper layer of the application, such that both the ParentVM and ChildVM are not directly communication with each other, but only with that shared Repository. The UI state is already complex enough, it’s usually better to try and eliminate any additional complexity you can, pushing business logic back into the Domain / Data layers to help keep things more appropriately separated from one another. Coupling two VMs directly to one another introduces a lot of complexity with things like managing their lifecycles, synchronizing states, etc. and is mentally more difficult to understand than keeping a contract that VMs only talk to Repositories (which should not be sensitive to UI Lifecycles)
z
Moving it up a layer in the arch stack is probably the right call. But better view model libraries like circuit and almost anything from the Android community in the last couple years make it very easy to form hierarchical relationships between view models.
r
Apparently I can't
@Inject
a
@Singleton
into a ViewModel?
c
The lifecycle of ViewModels and the way the Android framework instantiates them makes DI a notable pain point. If you’re using Hilt, you can inject normally by annotating the ViewModel class with @HiltViewModel. Otherwise, there’s some boilerplate that’s required to inject dependencies into a VM.
r
I've got everything annotated via
@HiltViewModel
🤔
Basically
Copy code
interface ConnectionCache {
    fun put(id: Long, connection: BrokerConnection)
    fun get(id: Long): BrokerConnection?
}
Copy code
@Provides
    @Singleton
    fun provideConnectionCache(): ConnectionCache = ConnectionCacheImpl()
s
When you say that you can't what do you mean? It crashes? You don't get a singleton? Something else?
r
Copy code
scoped with @dagger.hilt.android.scopes.ViewModelScoped may not reference bindings with different scopes:
Ah duh, different module, gotcha
p
Not sure how outdated this answer is but it could be worth checking it out: https://stackoverflow.com/questions/69642441/how-to-share-a-viewmodel-between-navgraph-components-only