Is there any recommendation to handle UI as State ...
# compose
l
Is there any recommendation to handle UI as State ? I currently have a Flow<UIState>, UIState being a sealed class. In my Screen with a when(uiState) depending of the value I display different Composable. The thing is, I crash when a different value is pushed (for example Loading -> Success is fine, but Success -> Error I crash). Any idea why ? 🤔 Code is in thread
inside my ViewModel:
Copy code
sealed class HomeUIState {
    object Loading : HomeUIState()
    data class Error(val homeErrorConfiguration: HomeErrorConfiguration) : HomeUIState()
    data class Explore(val sectionList: List<Section>) : HomeUIState()
}

val uiState: Flow<HomeUIState> = homeInteractor.homeState.map { //map the result from what the business logic class is doing (call to repository and stuff) to an uiState}
inside my Composable Screen:
Copy code
val uiState by homeViewModel.uiState.collectAsState(HomeUIState.Loading)
when (uiState) {   
   is HomeUIState.Error -> { //Displaying Error Screen}
   is HomeUIState.Explore -> { //Displaying "success" screen}
   else -> { //Displaying loading screen }
}
When opening the app it's working fine. I have the Loading -> Error or Loading -> Explore, but if a new event is trigger the app crash because inside the composable screen it's doing a cast inside the wrong switch.
b
Copy code
val viewState by rememberFlowWithLifecycle(viewModel.state)
    .collectAsState(initial = PhotoDiscoveryViewState.Empty)
Copy code
@Composable
fun <T> rememberFlowWithLifecycle(
    flow: Flow<T>,
    lifecycle: Lifecycle = LocalLifecycleOwner.current.lifecycle,
    minActiveState: Lifecycle.State = Lifecycle.State.STARTED
): Flow<T> = remember(flow, lifecycle) {
    flow.flowWithLifecycle(
        lifecycle = lifecycle,
        minActiveState = minActiveState
    )
}
l
flowWithLifecycle
is an API from which library ?
b
androidx.lifecycle
2.4.0-alpha01
👍 1
l
ah I'm using the stable version that's why (2.3.1)
and this solved the cast issue ?
b
started w/ this implementation so I didnt actually hit a cast issue. But this is running right now in production w/ no issues.
c
@Lucien Guimaraes Do you have a small reproducible case I can look at? I cannot tell what might be wrong from the snippet provided.
l
I don't have a small project to reproduce the issue, as for now I was implementing it in a prod app. But I can share the error log
btw I tried your option @brandonmcansh and I still have the crash
b
oh your UIState is a sealed class?
l
yes, that's what I said in the first message 😅 and you can see that in the snippet
b
those objects don’t equal
so they can’t cast across
i’d convert your viewstate to a data class and handle actions
hoist the navigation effect and handle it higher than your viewstate
l
those objects don’t equal
so they can’t cast across
What do you mean by that ? 🤔 I'm not sure to understand
m
did it means, we have to use
data class
instead of using
sealed class
when collecting the state? cmiiw
b
The sealed class entities are only comparable via
is
and aren't actually equal entities
3
l
Just fixed my crash, it was an hoist issue and it's now working like a charm
👍 2
The sealed class entities are only comparable via 
is
 and aren't actually equal entities
Yeah I know that but I don't know why you said it was an issue regarding my case, I'm already doing a comparison with
is
m
Did you mean hoist issue, you used
flowWithLifecycle
to fix ur crash?