I have an issue with view model, when I do a network call/viewModel validation, and then the re composition happens (for example Textfield onValueChange) the viewModel holds the reference to the last "state" from the viewModel is any way to "observe" the state only once? similar to SingleLiveEvent
or should I "clear" the state from my viewModel somehow?
here is an Example
@Composable
fun TestViewModelStateCompose(viewModel: TestViewModel) {
Column(modifier = Modifier.fillMaxSize()) {
var email by remember { mutableStateOf("") }
var error by remember { mutableStateOf<String?>(null) }
var lceState = viewModel.lceState.observeAsState().value
when (lceState) {
is Lce.Content -> {
// do something
if(lceState.result.not()){
error = "Wrong email :/"
}
}
is Lce.Error -> {
error = "Wrong email"
}
Lce.Loading -> {
//loading
}
null -> {}
}
TextField(
value = email, onValueChange = {
email = it
error = null
},
modifier = Modifier.fillMaxWidth()
)
error?.let {
Text(
text = it,
style = MaterialTheme.typography.labelMedium,
color = MaterialTheme.colorScheme.error,
modifier = Modifier
.padding(horizontal = 16.dp)
.padding(top = 8.dp)
.fillMaxWidth(),
maxLines = 1
)
}
Spacer(modifier = Modifier.weight(1f))
Button(
onClick = {
viewModel.validateEmail()
},
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 32.dp)
) {
Text(
text = "Validate email",
)
}
}
}
sealed class Lce {
object Loading : Lce()
data class Content(val result: Boolean) : Lce()
data class Error(val error: Throwable) : Lce()
}
class TestViewModel() : ViewModel() {
val lceState = SingleLiveEvent<Lce>()
private val isValid = false
fun validateEmail() {
if (isValid) {
// do something
} else {
viewModelScope.launch {
//place holder, the email is always invalid for test
flowOf(false)
.onStart {
// simulate call
delay(1000)
lceState.postValue(Lce.Loading)
}
.catch { lceState.postValue(Lce.Error(it)) }
.collect {
lceState.postValue(Lce.Content(it))
}
}
}
}
}
My main issue is when i call "validate emaial" and then I'm listening the
var lceState = viewModel.lceState.observeAsState().value
this works as expected, then I want to "clear" the error just setting to null, however this is being overriden by viewModel.lceState.observeAsState()
because in every re composition it holds the last value. is possible to "observe" as only one time? or "autoClear" after the compose comsume this events?
Thanks a lot