Having an UIState like this: ```sealed interface M...
# compose
p
Having an UIState like this:
Copy code
sealed interface MyModelUiState {
    object Loading : MyModelUiState
    data class Error(val throwable: Throwable) : MyModelUiState
    data class Success(val data: List<String>) : MyModelUiState
}
What happens if you need to have multiple variables more that can coexist in for example two of the three sealed states (error and success for example)... how to deal with that? for example:
Copy code
val showDialog
val text
val showButton
val showTitle
etc...
p
What about sealed class instead with the common shared parameters. Although in reality you can keep the sealed interface, define the parameter in each class. And just make sure you copy the old values when doing the state transitions.
c
While representing UI state as a sealed class sounds nice in theory, in practice, I've found that UI states are rarely able to be defined nicely in sealed interfaces/classes. I always use a data class to define the state, and just let the application logic be responsible for making certain combinations of properties be mutually exclusive. I've got a longer explanation of my opinions here.
3
👍 3
p
Great article. I see your points. I like sealed class because the reasons described in the Google documentation link shared in your article. I like it because somehow it helps to discretize the state in smaller sub-states that only makes sense for one specific component. But I do get your point 👍
p
Pablichenko can you show me your sealed class proposal with code?
p
Sure
Copy code
sealed class UiState(val commonProperty: String) {

  class Initial(val commonProperty: String) : UiState(commonProperty)

  class Loading(val commonProperty: String) : UiState(commonProperty)
  
  class Error(
    val commonProperty: String
    val propertyShared2: Boolean
  ) : UiState(commonProperty)
  
  class Success(
    val commonProperty: String
    val propertyShared2: Boolean
  ) : UiState(commonProperty)
  
}

_uiState: UiState = UiState.InitialState("Test")
Now, when you do the state transitions you need to ensure you copy the value from previous state
Copy code
fun transitionInitialToLoading(initialState: UiState.Initial){
  
  _uiState = UiState.Loading(initialState.commonProperty)
}

fun transitionLoadingToError(loadingState: UiState.Loading) {
  
  _uiState = UiState.Error(
    commonProperty = loadingState.commonProperty,
    propertyShared2 = false
  )
  
}

fun transitionErrorToSuccess(errorState: UiState.Error) {
  
  _uiState = UiState.Error(
    commonProperty = errorState.commonProperty,
    propertyShared2 = errorState.propertyShared2
  )
  
}
This is just for illustration purposes, you normally won’t have a transition from error to success. But rather from error to loading then to success. Like in Casey’s article