StateFlow don't emit when the new value same last value

Viewed 3379

I have a login form. I use StateFlow to send LoginResult (after call API) from ViewModel to Activity. In the Activity, I will show an error dialog if login failed.
It works well for the first time but from the second time I login failed, the error dialog won't show again. I tested both .value and .emit on StateFlow

private val _loginResult = MutableStateFlow(LoginResult())
val loginResult: StateFlow<LoginResult> = _loginResult

fun login(email: String, password: String) {
    viewModelScope.launch {
        when (val result = loginRepository.login(email, password)) {
            is Result.Fail-> {
                _loginResult.value = LoginResult(error = "Login failed")
                // _loginResult.emit(LoginResult(error = "Login failed")) same issue
            }
            ...
       }
   }
}
2 Answers

For this case, I use SharedFlow so my Activity still able to collect the new value even it same the last value

private val _loginResult = MutableSharedFlow<LoginResult>()
val loginResult: SharedFlow<LoginResult> = _loginResult

...
_loginResult.emit(LoginResult(error = "Login failed"))

Another possible solution but it's not good is change my current data class LoginResult(...) to class LoginResult. Then every new instance of LoginResult will different

That's by default. What you could do is to emit one value when the login is in progress, before emitting the result. That way you would have a sequence like:

in_progress -> error -> in_progress -> error

Apps usually display a spinner or something when the in_progress or loading or whatever is emitted.

Related