Careeroza
Real World Example
Jetpack Compose Screen
This is how a production Android screen (e.g. a product list in a shopping app) consumes a sealed UI state. The ViewModel emits states; the composable draws each one.
sealed interface ProductsUiState {
data object Loading : ProductsUiState
data class Success(val products: List<Product>) : ProductsUiState
data class Error(val message: String) : ProductsUiState
}
@Composable
fun ProductsScreen(viewModel: ProductsViewModel = viewModel()) {
val state by viewModel.uiState.collectAsStateWithLifecycle()
when (val s = state) {
ProductsUiState.Loading -> CircularProgressIndicator()
is ProductsUiState.Success -> LazyColumn {
items(s.products) { product -> ProductRow(product) }
}
is ProductsUiState.Error -> ErrorView(s.message, onRetry = viewModel::refresh)
}
}Mapping Network Results to UI State
Example
A simplified repository + ViewModel flow: network outcomes are sealed too, and a pure function turns them into UI state.
sealed interface ApiResult<out T> {
data class Ok<T>(val data: T) : ApiResult<T>
data class HttpError(val code: Int) : ApiResult<Nothing>
data object NoInternet : ApiResult<Nothing>
}
sealed interface UiState {
data object Loading : UiState
data class Content(val items: List<String>) : UiState
data class Error(val message: String, val canRetry: Boolean) : UiState
}
fun toUiState(result: ApiResult<List<String>>): UiState = when (result) {
is ApiResult.Ok -> UiState.Content(result.data)
is ApiResult.HttpError -> when (result.code) {
401 -> UiState.Error("Session expired. Please log in again.", canRetry = false)
in 500..599 -> UiState.Error("Server is busy. Try again.", canRetry = true)
else -> UiState.Error("Something went wrong (${result.code})", canRetry = true)
}
ApiResult.NoInternet -> UiState.Error("You are offline", canRetry = true)
}
fun main() {
val responses = listOf(
ApiResult.Ok(listOf("iPhone 16", "Galaxy S25")),
ApiResult.HttpError(401),
ApiResult.HttpError(503),
ApiResult.NoInternet,
)
responses.forEach { println(toUiState(it)) }
}Output
Content(items=[iPhone 16, Galaxy S25]) Error(message=Session expired. Please log in again., canRetry=false) Error(message=Server is busy. Try again., canRetry=true) Error(message=You are offline, canRetry=true)