Search code examples
androidkotlinmvvmretrofitandroid-room

Wait with second coroutine until the first one prepare needed data


I have a fragment, where in its onCreateView fun, I've made two coroutines.

The first one, collect some data, from database, and the second one, performs an api call, but as a parameter it get's value, that is collected from database.

I'd like to make the second coroutine wait, until the first one will be ready with data, and then, the second one should run. How I may make it work? These coroutines look like this:

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
 ...



viewLifecycleOwner.lifecycleScope.launch {
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                    myViewModel.someData.collect { data ->
        when (data) {
          is DBState.Success -> {
            someVar = data
 }
  ...
}


viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
myViewModel.makeCall(someVar) myViewModel.response.observe(viewLifecycleOwner, Observer { status ->
                when (data) {
                  is NetStatus.Success -> {
                    someVar = data
         }
          ....
        }

Solution

  • I'm not sure if I understand exactly, but I think what you're saying is you want to postpone one of these two coroutines until the other receives its first value from the Flow or LiveData. Then the second coroutine can begin collecting or observing, while the first one continues collecting or observing normally.

    You can do it like this. Declare the second coroutine first, passing CoroutineStart.LAZY to the launch call and storing the Job in a property. Then call start() on that Job inside the other coroutine in the observer or collector. After the first item is received, further calls to start() will be ignored automatically.

    val dependentCoroutine = viewLifecycleOwner.lifecycleScope.launch(CoroutineStart.LAZY) {
        repeatOnLifecycle(Lifecycle.State.STARTED) {
            myViewModel.makeCall(someVar) 
            //...
        }
    }
    
    viewLifecycleOwner.lifecycleScope.launch {
        repeatOnLifecycle(Lifecycle.State.STARTED) {
            myViewModel.someData.collect { data ->
                when (data) {
                    is DBState.Success -> {
                        someVar = data
                        dependentCoroutine.start()
                    }
                }
            }
        }
        //...
    }