I don't really understand how LauchedEffect works, can you explain to me?
Here is the context, I make a account.get() call to find out if a user session exist or not in my app, depending on the case I return userExist = true or = false
But in all cases it returns me a return = true to know that I must launch my LaunchedEffect at that moment, here is my code
SplashUiState:
data class SplashUiState(
val result: Boolean = false,
val userExist: Boolean = false,
val error: List<Pair<String, String>> = emptyList()
)
SplashViewModel:
private val _state = MutableStateFlow(SplashUiState())
val state = _state.asStateFlow()
...
init {
delay(2000)
checkSessionExist()
}
...
private suspend fun checkSessionExist() {
when(val account = repository.getAccount()) {
is ResponseResult.Error -> {
Log.d("SplashViewModel", "${account.code}" + " ${account.message}")
_state.update { it.copy(result = true, userExist = false,
userError = listOf(
"code" to "${account.code}",
"message" to "${account.message}"
)
) }
}
is ResponseResult.Success -> {
Log.d("SplashViewModel", "${account.data}")
_state.update { it.copy(result = true, userExist = true) }
}
}
}
SplashScreen:
val state by viewModel.state.collectAsState()
LaunchedEffect(key1 = state.result) {
if (state.userExist) {
Log.d("LaunchedEffect", "user exist")
navController.navigate(AppRoutes.OVIDE_SCREEN) {
popUpTo(AppRoutes.SPLASH_SCREEN) {
inclusive = true
}
}
} else {
Log.d("LaunchedEffect", "user not exist")
navController.navigate(AppRoutes.WELCOME_SCREEN) {
popUpTo(AppRoutes.SPLASH_SCREEN) {
inclusive = true
}
}
}
}
My code seems good to me, well structured but when the user exists userExist = true it launches my code in the else and not in my if
How is this done?
The code line
LaunchedEffect(key1 = state.result) {}
means that the code within the LaunchedEffect
will be executed
state.result
changes.It does not mean that the LaunchedEffect
will only be executed once the state.result
value is true
. So your app will immediately go to the WELCOME_SCREEN before it even finished checking whether the session exists.
Please try to change your code like this:
LaunchedEffect(key1 = state.result) {
if (state.result) {
if (state.userExist) {
Log.d("LaunchedEffect", "user exist")
navController.navigate(AppRoutes.OVIDE_SCREEN) {
popUpTo(AppRoutes.SPLASH_SCREEN) { inclusive = true }
}
} else {
Log.d("LaunchedEffect", "user not exist")
navController.navigate(AppRoutes.WELCOME_SCREEN) {
popUpTo(AppRoutes.SPLASH_SCREEN) { inclusive = true }
}
}
}
}
This will make the navigation happen once loading is finished.