Colton Idle
09/05/2021, 4:01 AMColton Idle
09/05/2021, 4:05 AMval happy: Flow<Boolean> = prefs.data
.map { preferences ->
preferences[isHappy] ?: false
}
and then I show it via
Text(text = "happy: " + vm.happy.collectAsState(false).value)
The problem is that even after I save to prefs after setting happy to true, when I restart the app I see, for a split second that the text says "happy: false" even though the flowable is actually true.
I think what I'm really after is maybe NOT using a flowable in this case, because happy is critical to my application (think logged in state bool or something) and so I guess I don't actually want this as a flowable? I want my application to wait until I have that first value.
Any help is appreciated!K Merle
09/05/2021, 4:26 AMColton Idle
09/05/2021, 4:46 AMval happy: Flow<Boolean> = prefs.data
.map { preferences ->
preferences[isHappy] ?: false
}
val happySynchronous: Boolean = runBlocking {
prefs.data
.map { preferences ->
preferences[isHappy] ?: false
}
}
Text(text = "happy: " + vm.happy.collectAsState(vm.happySynchronous).value)rajesh
09/05/2021, 4:58 AMColton Idle
09/05/2021, 5:06 AMrajesh
09/05/2021, 5:08 AMFrancesc
09/05/2021, 5:12 AMK Merle
09/05/2021, 6:30 AMNikola Drljaca
09/05/2021, 6:56 AMstateIn() to convert the flow into a state(hot) flow. Or maybe since the value is boolean you could use .first() on the flow to retrieve one value. Its a terminal operator so it should give you the value right away.Michael Paus
09/05/2021, 7:01 AMK Merle
09/05/2021, 7:29 AMfalse and flow returning true makes bad UX sometimes.Michael Paus
09/05/2021, 7:33 AMOleksandr Balan
09/05/2021, 7:43 AMcollectAsState without init value only on the StateFlow. So you have to use stateIn to convert Flow from DataStore to the StateFlow. But stateIn requires an inital value.Michael Paus
09/05/2021, 7:45 AMJavier
09/05/2021, 8:54 AMOleksandr Balan
09/05/2021, 1:40 PMstateIn without initial value is suspend method, thus it may be not be possible to use when defining a property baked by flow from DataStore.
@Colton Idle I would say in such case the third state should by used and set as initial value. Either null or convert boolean from DataStore to some 3-state enum: unknown / happy / unhappy 🤷Javier
09/05/2021, 1:49 PMJavier
09/05/2021, 1:50 PMColton Idle
09/05/2021, 2:15 PMOleksandr Balan
09/05/2021, 2:25 PMval happy: StateFlow = ...) you cannot use suspend functions.Javier
09/05/2021, 2:28 PMJavier
09/05/2021, 2:29 PMrajesh
09/05/2021, 2:31 PMisLoggedIn StateFlow in main activity as it should decide which compose screen to display, but you can use similar in compose screen)
Inside viewmodel
val isLoggedIn = preferenceManager.isLoggedIn.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(),
initialValue = null
)
Inside activity
lifecycleScope.launchWhenCreated {
mainViewModel.isLoggedIn.collect {
it?.apply {
if (this) {
setContent {
MainScreen()
}
} else {
setContent {
AuthScreen()
}
}
}
}
}Ian Lake
09/05/2021, 10:10 PMLoading, LoggedIn, and LoggedOut - you really don't want to ever be blocking the UI thread on disk access (and any persisted data is, by definition, disk access, at some level). That way you can delay your UI until you're out of the Loading stateColton Idle
09/05/2021, 10:23 PM