I have a viewmodel that subscribes to logged in us...
# compose-android
c
I have a viewmodel that subscribes to logged in user ID changes. When my screen is showed up, I want to log to an analytics service that my user saw a screen with the current id. That seems to work fine, but when I go to a different screen and come back to my original screen, even though the viewmodel hasn't been cleared, the composable gets kicked off again and I end up logging. I feel like I'm just missing something with how Flow's work. In my VM I have
Copy code
fun userIdFlow(): Flow<UserId> = userFlow.distinctUntilChangedBy { it?.it }.onEach { analyticLog(it) }.shareIn(viewModelScope, Lazily)
and my composable screen has
Copy code
LaunchedEffect(Unit){
viewModel.userIdFlow().collect()
}
I'm probably doing something completely wrong. but im still a flow noob so appreciate pointing out any glaring issue here. thanks!
a
When you use
shareIn
or
stateIn
, always make it a member instead of a function, otherwise every time you call the function a new flow will be created, which essentially makes
shareIn
or
stateIn
useless.
👀 1
c
Thanks. I think I'm closer to a solution. I think my issue stems from the fact athat I might have 3 viewmodels that are listening to this flow... but i want only the first one to respond to the event. I guess it's more of a queue than a flow?
a
I don’t understand your issue. The
onEach
operator is applied before
shareIn
, and once the sharing starts it won’t stop (because of
Lazily
), so it’ll just work as you expect (i.e.
onEach
runs once for each value) if you make it a class member.
z
Channels are queues, Flows are not
c
Yeah. I went for a channel. Sorry, the root issue is caused by the fact that we have a really bad current setup of viewmodels and basically viewmodels never clear 😭 (Ian Lake would be sad at our custom navigation setup) so i was getting multiple invocations. Thanks for the initial pointer @Albert Chang as that unblocked me to find my actual issue. TIL (and used) channels for the first time!