It could create data ambiguity if the data has been produced by mixing reactive and non-reactive code. The reactive data may notified earlier without updating non-reactive data.
Let me explain an example scenario. Let's assume LoginRepository provides LoginState by observing LoginService. It is mixing reactive LoginService.loginStatusFlow with non-reactive LoginService.accountData. There could be a situation where loginStatusFlow has been notified isLogin=true but accountData not initializing yet. In this case LoginRepository could provide Logout with wrong userId or crashing the application.
Problem
sealed interface LoginState {
data class Login(val userId: String) : LoginState
object Logout : LoginState
}
class LoginRepository(
private val loginService: LoginService
) {
val loginState = loginService.loginStatusFlow.map { loginStatus ->
if (loginStatus.isLogin) {
val userId = loginService.accountData.userId
LoginState.Login(userId = userId)
} else {
LoginState.Logout
}
}
}
The solution could be mixing only reactive data to produce new data. In the example, to combine two reactive loginStatusFlow and accountDataFLow solve the issue and ensure proper data emit by LoginRepository.
Solution
class LoginRepository(
private val loginService: LoginService
) {
val loginState = loginService
.loginStatusFlow
.combine(loginService.accountDataFLow) { loginStatus, accountData ->
if (loginStatus.isLogin) {
val userId = accountData.userId
LoginState.Login(userId = userId)
} else {
LoginState.Logout
}
}
}
Comments