Colton Idle
09/05/2021, 4:01 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 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 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