How to collect data inside a loop using flow and coroutines

Viewed 919

I'm new to using flow and coroutines and I would like you to help me with the following problem:

I have the useCases.getScheduleList() and useCases.getScheduleDetails() methods that return a Flow. And I need to call useCases.getScheduleList() to get the schedule list and then call useCases.getScheduleDetails() for each item in the schedule list. Following is my attempt:

    viewModelScope.launch {
        useCases.getScheduleList().collect {
            val scheduleList = it
            val schedulesWithDetails = arrayListOf<ScheduleWithDetails>()

            for (schedule in scheduleList) {
                launch {
                    useCases.getScheduleDetails(schedule.code)
                        .collect { detail ->
                            schedulesWithDetails.add(
                                newScheduleWithDetail(
                                    schedule,
                                    detail.body
                                )
                            )
                        }
                }
            }

            // updateUI is called before collect add items to schedulesWithDetails
            updateUI(schedulesWithDetails)
        }
    }
}

In the code above I can collect the listing and also collect the detail of each item in the listing and add the results to my schedulesWithDetails but I cannot use schedulesWithDetails with the data already added because the updateUI() method does not wait for the collect process to finish in then be executed.

Can anyone help me with ideas/suggestions for this problem?

1 Answers

Try this out:

viewModelScope.launch {
    useCases.getScheduleList().map { scheduleList ->
        scheduleList.map { async { useCases.getScheduleDetails(it).first() } }.awaitAll()
    }.collect { schedulesWithDetails ->
        updateUi(schedulesWithDetails)
    }
}
Related