How to update a mutablestate uistate to set current selected item in a viewmodel? I have this uistate class, and need to change selectedBookId value.
sealed interface BooksGridUiState {
data class Success(
val booksList: List<BookData>,
val selectedBookId: String?
) : BooksGridUiState
object Error : BooksGridUiState
object Loading : BooksGridUiState
}
This is the variable in the viewmodel:
var uiState: BooksGridUiState by mutableStateOf(BooksGridUiState.Loading)
private set
Can't do the trick of calling
.update {
it.copy(
Because this is not a mutablestateflow, and I'm following a codelab and must use mutablestate (editado)
is it correct to do it this way?
fun selectBook(id: String) {
(uiState as BooksGridUiState.Success).let {
uiState = BooksGridUiState.Success(it.booksList, id)
}
}
maybe is better to do it this way?
fun selectBook(id: String) {
(uiState as BooksGridUiState.Success).let {
uiState = it.copy(selectedBookId = id)
}
}
Use this:
uiState = when (val state = uiState) {
is BooksGridUiState.Success -> state.copy(
selectedBookId = id,
)
is BooksGridUiState.Error -> TODO()
is BooksGridUiState.Loading -> TODO()
}
You said you are doing this because you follow a Codelab. This approach is ok if it is just used for academic purposes, but in any real-world application you shouldn't use a Compose State in your view model, you should use a MutableStateFlow instead.
Regarding your update to the question: If you just want to ignore the cases where the current state is Error
or Loading
then I would suggest a variation of your second proposed solution:
fun selectBook(id: String) {
(uiState as? BooksGridUiState.Success)?.let {
uiState = it.copy(selectedBookId = id)
}
}
I used as?
with a ?
which won't fail with a runtime exception if uiState
isn't castable to Success
(which is the case for Error
and Loading
). Instead it will return null so that the following ?.let
is skipped entirely.