Ryosuke Yamada
03/28/2022, 4:13 PMFlow
or StateFlow
.
Many codes expose Flow
in repository, and convert to StateFlow
in ViewModels like this.
val userState: StateFlow<User?> = userRepository.userFlow.stateIn(viewModelScope, Eagerly, null)
This case always show null state on UI started, even if repository has initial value.
This problem may be solved by exposing StateFlow
instead of regular Flow
in repository, is it bad practice?Nick Allen
03/28/2022, 11:41 PMeven if repository has initial value.Repository data usually comes from a web-service or database in which case it takes time to get an "initial value" so it's not really "initial" at all. What kind of repository do you have such that you think it has an initial value? Do you, for example, want a list to show as empty while data is loading or some similar default value while loading? If you changed the UI to show a spinner, would you need to make a change in your repository. If you need to change the repository in order to change the way data is presented, then that is not a great design.
gildor
03/29/2022, 2:04 AMThis case always show null state on UI started, even if repository has initial valueIt’s implementation detail, userFlow can expose StateFlow if it under it’s contract to provide default value (even if it null) The reason why you get null at the first place is because subscription is asynchronous, so first it will have null as default value in StateFlow, after that it will subscribe on flow and start collecting.
Ryosuke Yamada
03/29/2022, 2:39 AMgildor
03/29/2022, 2:46 AMBut how to avoid meaningless transition in ViewModel(and UI) without exposing StateFlow?This transition is caused by asyncronous nature of subscription. There are 2 points which are asyncronous: stateIn and subscription on userState. In theory if you use Dispatchers.Main.immediate and do subscription on main thread it should be almost immediate (so not exactly, because you will still get default value)
Ryosuke Yamada
03/29/2022, 6:45 AMgildor
03/29/2022, 6:50 AMYou mean this transition itself is unavoidableWhen you create StateFlow from Flow and immediately subscribe on it (so if eager subscription is slower than subscriber), yes, it’s correct
Ryosuke Yamada
03/29/2022, 6:55 AM