Sanendak
07/14/2021, 10:00 PMval scope = rememberCoroutineScope()
LaunchedEffect(scope) {
viewModel.effect.collect {
when(it) {
is ShowEffect1 -> //Runs first from VM and shows
is ShowEffect2 -> //Runs after and doesn't run here
}
}
}
In ViewModel:
private val _effect = MutableSharedFlow<CharactersScreenEffect>()
val effect = _effect.asSharedFlow()
I don't want to use .asStateFlow because it need initial state.Zach Klippenstein (he/him) [MOD]
07/14/2021, 10:01 PMShowEffect1
case?Sanendak
07/14/2021, 10:03 PMZach Klippenstein (he/him) [MOD]
07/14/2021, 10:03 PMZach Klippenstein (he/him) [MOD]
07/14/2021, 10:03 PMrememberCoroutineScope
with LaunchedEffect
Sanendak
07/14/2021, 10:05 PMLaunchedEffect(scope) {
viewModel.effect.collect { effect ->
when (effect) {
is CharactersScreenEffect.ShowSnackbar -> {
snackbarState.showSnackbar(
message = effect.character,
actionLabel = "Dismiss",
duration = SnackbarDuration.Indefinite
)
}
CharactersScreenEffect.CloseSnackbar -> {
snackbarState.currentSnackbarData?.dismiss()
}
}
}
}
Full codeSanendak
07/14/2021, 10:05 PMval snackbarState = remember { SnackbarHostState() }
Zach Klippenstein (he/him) [MOD]
07/14/2021, 10:07 PMshowSnackbar
suspends until the snackbar goes away. If that second emission comes while the snackbar is still showing, it won’t be delivered to your collector because it’s still suspended. If you wrap snackbarState.showSnackbar
in a launch
, i think it will fix it.Sanendak
07/14/2021, 10:11 PMZach Klippenstein (he/him) [MOD]
07/14/2021, 10:13 PMscope
to LaunchedEffect
(which is effectively a no-op), you might want to pass viewModel.effect
since that’s the object you’re operating on inside the effect. E.g. If, for some reason, the view model would ever return a different effect
, you’d need to cancel collecting on the old one but not the new one.Sanendak
07/14/2021, 10:13 PM