MaestroLoadableResult
Overview
MaestroLoadableResult is a sealed interface that represents the state of an asynchronous operation in the Maestro SDK. It follows a common pattern for handling loading states, success results, and error conditions in a type-safe manner.
Syntax
sealed interface MaestroLoadableResult<out T : Any>
Type Parameters
| Parameter | Description |
|---|---|
T | The type of data contained in a successful result. Must be a non-null type extending Any. |
Sealed Subclasses
Success
Represents a successful operation with data.
data class Success<T : Any>(
val data: T
) : MaestroLoadableResult<T>
Properties:
data: T- The successfully loaded data
Error
Represents a failed operation with error information.
data class Error(
val source: MaestroNetworkError
) : MaestroLoadableResult<Nothing>
Properties:
source: MaestroNetworkError- Information about the error that occurred
Loading
Represents an operation that is currently in progress.
data object Loading : MaestroLoadableResult<Nothing>
Usage Example
Basic Pattern Matching
fun handleResult(result: MaestroLoadableResult<UserData>) {
when (result) {
is MaestroLoadableResult.Loading -> {
// Show loading indicator
showLoadingSpinner()
}
is MaestroLoadableResult.Success -> {
// Handle successful data
val userData = result.data
displayUserData(userData)
}
is MaestroLoadableResult.Error -> {
// Handle error
val error = result.source
showErrorMessage(error.message)
}
}
}
With Key Plays Data
override fun keyPlaysData(): MaestroLoadableResult<KeyPlaysData> {
return if (isLoading) {
MaestroLoadableResult.Loading
} else if (keyPlaysDataAvailable) {
MaestroLoadableResult.Success(currentKeyPlaysData)
} else {
MaestroLoadableResult.Error(
MaestroNetworkError(message = "Failed to load key plays")
)
}
}
Reactive UI Updates
class MyViewModel : ViewModel() {
private val _dataState = MutableStateFlow<MaestroLoadableResult<MyData>>(
MaestroLoadableResult.Loading
)
val dataState: StateFlow<MaestroLoadableResult<MyData>> = _dataState
fun loadData() {
_dataState.value = MaestroLoadableResult.Loading
viewModelScope.launch {
try {
val data = repository.fetchData()
_dataState.value = MaestroLoadableResult.Success(data)
} catch (e: Exception) {
_dataState.value = MaestroLoadableResult.Error(
MaestroNetworkError(message = e.message ?: "Unknown error")
)
}
}
}
}
Helper Extension Functions
// Extension to check if result is successful
fun <T : Any> MaestroLoadableResult<T>.isSuccess(): Boolean {
return this is MaestroLoadableResult.Success
}
// Extension to get data or null
fun <T : Any> MaestroLoadableResult<T>.getOrNull(): T? {
return (this as? MaestroLoadableResult.Success)?.data
}
// Extension to map success data
fun <T : Any, R : Any> MaestroLoadableResult<T>.map(
transform: (T) -> R
): MaestroLoadableResult<R> {
return when (this) {
is MaestroLoadableResult.Success -> MaestroLoadableResult.Success(transform(data))
is MaestroLoadableResult.Error -> this
is MaestroLoadableResult.Loading -> MaestroLoadableResult.Loading
}
}
Common Patterns
Loading State Management
class DataManager {
private var state: MaestroLoadableResult<Data> = MaestroLoadableResult.Loading
fun getData(): MaestroLoadableResult<Data> = state
suspend fun refreshData() {
state = MaestroLoadableResult.Loading
state = try {
val newData = fetchFromNetwork()
MaestroLoadableResult.Success(newData)
} catch (e: Exception) {
MaestroLoadableResult.Error(
MaestroNetworkError(message = e.localizedMessage)
)
}
}
}
Composable UI (Jetpack Compose)
@Composable
fun DataScreen(result: MaestroLoadableResult<MyData>) {
when (result) {
is MaestroLoadableResult.Loading -> {
CircularProgressIndicator()
}
is MaestroLoadableResult.Success -> {
DataContent(data = result.data)
}
is MaestroLoadableResult.Error -> {
ErrorView(error = result.source)
}
}
}
Benefits
- Type Safety: Compile-time guarantee that all states are handled
- Exhaustive When: Kotlin ensures all sealed class cases are covered
- Clear State Representation: Explicitly models loading, success, and error states
- Null Safety: Eliminates null checks by using proper types
- Composability: Easy to combine and transform results
See Also
- keyPlaysData - Delegate method that returns MaestroLoadableResult
- MaestroEventDelegate - Interface that uses MaestroLoadableResult
- MaestroNetworkError - Error type used in Error state