'Mutable shared flow failed to collect emitted values

I started on building Apps using Android Compose and am learning Kotlin's coroutine and stuff. Below are the samples of code that I have written for an app, where I tried to use MutableSharedFlow emit and collectLatest for updating UI. Init Method of ViewModel

init {
    try {
        viewModelScope.launch {
            _state.value = state.value.copy(
                isSearchStarted = true
            )
            userCredRepository.getCred().also {security ->
                if (security?.authToken.isNullOrEmpty()){
                    println("RECEIVED NULL TOKEN")
                    delay(100)
                    _eventFlow.emit(LoginSignUpEvent.ErrorEvent("Please Login to continue", ""))
                    _state.value = state.value.copy(
                        isSearchStarted = false
                    )
                }else{
                    delay(100)
                    _eventFlow.emit(LoginSignUpEvent.SuccessEventLogIn("Subscribing"))
                }

            }
        }
    }catch (ex: CancellationException){
        println(ex.message)
    }catch (ex: Exception){
       println(ex.message)
    }
}

This is the view modal for the Login SingUp screen. Here userCredRepository communicates with sqlite database, and fetches the token on the app startup.

Login SignUp Screen

 LaunchedEffect(true) {
    loginSignUpViewModal.eventFlow.collectLatest { event ->
        when (event) {
            is LoginSignUpEvent.ErrorEvent -> {
                state.snackbarHostState.showSnackbar(
                    message = event.message!!,
                    actionLabel = event.actionMessage
                )
            }
            is LoginSignUpEvent.SuccessEventSignUp -> {
                state.snackbarHostState.showSnackbar(
                    message = event.message!!,
                    actionLabel = event.actionMessage
                )
            }
            is LoginSignUpEvent.SuccessEventLogIn -> {
                navController.popBackStack()
                navController.navigate(NotesScreen.HomeScreen.name)
            }
        }
    }
}

This is sample code of Login Sign Up Screen where I listen to MutableSharedFlow's emitted values. This is the first screen that is displayed when the app runs ,and navigates to another screen if token is present. So the issue here is that the emitted values are not caught until I add dely(100) (as in the first code sample line 10 & 16 from start) before emitting values in the ViewModal. I have attached the link to the project.Link to project

Below is the updated code using Channel instead of Mutable shared flow, here it works well.

private val _eventFlow = Channel<LoginSignUpEvent>()
val eventFlow = _eventFlow.receiveAsFlow()

val toggleLoginSignupScreen = mutableStateOf(false)
var passwordVisibility = mutableStateOf(false)

init {
    try {
        viewModelScope.launch {
            _state.value = state.value.copy(
                isSearchStarted = true
            )
            userCredRepository.getCred().also {security ->
                if (security?.authToken.isNullOrEmpty()){
                    _eventFlow.send(LoginSignUpEvent.ErrorEvent("Please Login to continue", ""))
                    _state.value = state.value.copy(
                        isSearchStarted = false
                    )
                }else{
                    _state.value = state.value.copy(
                        isSearchStarted = false,
                    )
                    _eventFlow.send(LoginSignUpEvent.SuccessEventLogIn("Subscribing"))
                }

            }
        }
    }catch (ex: CancellationException){
        println(ex.message)
    }catch (ex: Exception){
       println(ex.message)
    }
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source