I'm trying to learn how I should re-write my room database (dao, repository, viewmodel, room databse). My problem: The user pressed the save button on the UI, the onClick function does the following: 1 – Save records in the room database using the viewModelScope.launch function. 2 – Navigates to a different screen.

My question – what method you would use to wait for the viewModelScope.launch function to complete before navigates to the different screen. The issue I’m having is the current viewModel is closing which also closes all the viewModelScope.launch function before all of the records are saved.

onClick = {
        nextScreen = onSaveSelection()
        navHostController.navigate(route = Screen.ScoreCard.route)
}

fun onSaveSelection(): Int {
    deleteAllPlayerRecords()
    savePlayersRecord()
    saveScoreCardRecord()
    return Constants.DISPLAY_SCORE_CARD_SCREEN
}

I have read you shouldn’t use GlobalScope.launch function.

Thanks for the advice

1

There are 1 best solutions below

0
william xyz On

There's no need for much, you're just using coroutines incorrectly. Your viewModel should be using viewModelScope.launch, your method onSaveSelection should be like:

fun onSaveSelection() {
    viewModelScope.launch {
        deleteAllPlayerRecords()
        savePlayersRecord()
        saveScoreCardRecord()

        // once the suspended functions above excute, we can navigate to the next screen
        // by updating our observedAttribute with either LiveData or StateFlow
        observedAttribute.value = Constants.DISPLAY_SCORE_CARD_SCREEN
    }
}

// change your click event to
onClick = {
    onSaveSelection()
}

// and in your composable
val observedAttribute = viewModel.observedAttribute.collectAsState().value
LaunchedEffect(observedAttribute) {
    if (observedAttribute == Constants.DISPLAY_SCORE_CARD_SCREEN) {
        navHostController.navigate(route = Screen.ScoreCard.route)
    }
}

This way the navigation will only happen when the viewModel says so.