Skip to content

Instantly share code, notes, and snippets.

@AdnanHabibMirza
Last active July 31, 2024 23:58
Show Gist options
  • Save AdnanHabibMirza/d6403c5fe2f4b3a3621e12d05e5cad5a to your computer and use it in GitHub Desktop.
Save AdnanHabibMirza/d6403c5fe2f4b3a3621e12d05e5cad5a to your computer and use it in GitHub Desktop.
Streamlining State Management with a Generic Result Interface and Flow Mapper in Kotlin
sealed interface Result<out T> {
data class Success<T>(val data: T) : Result<T>
data class Error(val exception: Throwable) : Result<Nothing>
data object Loading : Result<Nothing>
}
fun <T> Flow<T>.asResult(): Flow<Result<T>> = map<T, Result<T>> { Result.Success(it) }
.onStart { emit(Result.Loading) }
.catch { emit(Result.Error(it)) }
class UsersViewModel : ViewModel() {
private val _usersUiState = MutableStateFlow<UsersUiState>(UsersUiState.Loading)
val usersUiState: StateFlow<UsersUiState> = _usersUiState
fun getUsers() {
viewModelScope.launch {
fetchUsers() // This is a suspend function that returns a Flow
.asResult()
.collectLatest { usersResult ->
when (usersResult) {
Loading -> {
_usersUiState.tryEmit(UsersUiState.Loading)
}
is Success -> {
val users = usersResult.data
_usersUiState.tryEmit(UsersUiState.Success(users))
}
is Error -> {
val exception = usersResult.exception
_usersUiState.tryEmit(UsersUiState.Error(exception))
}
}
}
}
}
sealed interface UsersUiState {
data class Success(val users: List<User>) : UsersUiState
data class Error(val exception: Throwable) : UsersUiState
data object Loading : UsersUiState
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment