Home > Software design >  Coroutine Scope correct implementation with states
Coroutine Scope correct implementation with states

Time:08-02

I am making a retail app using MVVM Architecture and Jetpack Compose.

Scenario.

  1. Create page for creating a store visit, there is a Save button on topbar.
  2. On click of save, have to show a dropdown menu with two items, Save and Save and Open, first option is to save the visit, second is to save and open the same visit detail page but with a visibility of navigation.

Issue: I am using Coroutine scope to save and navigate to other screen. I am showing 3ms delay, what if the response doesnt comes at 3 ms.how to show a message if the api fails. how this can be done in concrete way: Please suggest, as I need to show the navigation from save visit to the next save detail page.

 DropdownMenu(
            expanded = viewModel.isDropdownMenuExpanded,
            onDismissRequest = { viewModel.isDropdownMenuExpanded = false }
        ) {
           
            for (title in SaveVisitActions.values())
                DropdownMenuItem(
                    onClick = {
                        when (title) {
                            SaveVisitActions.SAVE -> {
                                viewModel.handleSave()
                            }
                            SaveVisitActions.SAVEANDOPEN -> {
                                CoroutineScope(Dispatchers.IO).launch {
                                    delay(3000)
                                    withContext(Dispatchers.Main) {
                                        if (viewModel.isCreateSuccess.value) {
                                            navController.navigate(
                                                "${Screen.VisitDetailScreen.route}/${viewModel.objectState.value?.id}"
                                            )
                                        }

                                    }
                                }
                                viewModel.handleSave()

                            }
                        }
                    }) {
                    Text(text = title.title)
                }
        }

CodePudding user response:

You could use join() function that is a suspending function, i.e it can be called from a coroutine or from within another suspending function. Job blocks all the threads until the coroutine in which it is written or have context finished its work. Only when the coroutine gets finishes, lines after the join() function will be executed.

CodePudding user response:

use await() method to wait for the value you are waiting for. I suppose you are waiting for the value of isCreateSuccess in your view model. create a job that waits for a value returned by a suspend function waiting for your success value from the view model.

val handleSave = async { waitForSuccess() }

if(handleSave.await()){
    viewModel.handleSave()
}else{
     // show your error here
}

suspend fun waitForSuccess() : Boolean{
    // get your Success Value from view model here
}
  • Related