Last active
October 6, 2024 13:01
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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