Natalia Chuzhmarova
09/07/2022, 7:49 AMfun data(): Flow = flowOf(
flowOf(cachedValue),
networkCallFlow
). flattenConcat()
which is then observed in a ViewModel and mapped to UI state
data()
.onEach { .. }
.map { uiState(data) }
.catch { emit(uiState(error)) }
It works fine when the network call succeeds. The problem is, when networkCallFlow
throws an exception (no network), the cachedValue
is never mapped, however it triggers the onEach
handler. My guess is that the emission of the cachedValue
does not guarantee that it will be observed, and the exception halts the Flow before the consumption of the cachedValue
happens or while it is in progress.
Is my understanding correct?
Is there any way to adjust the Flow to fit the requirements?
The code: https://pl.kotl.in/3U8jVprL-ephemient
09/07/2022, 8:19 AMflowOf(
flowOf(1),
flow { TODO() }
)
.flattenConcat()
.map { "value=$it" }
.catch { emit("error=$it") }
.collect { println("collect($it)") }
this prints out
collect(value=1)
collect(error=kotlin.NotImplementedError: An operation is not implemented.)
Francesc
09/07/2022, 6:54 PMonStart
Natalia Chuzhmarova
09/07/2022, 11:46 PMNatalia Chuzhmarova
09/08/2022, 1:21 AMephemient
09/08/2022, 1:41 AMCoroutineScope
like that is not good, but that's unrelated
made a much smaller reproducible case which makes the behavior more obvious:
suspend fun main() {
do {
val list = flow { emit(1); TODO() }.flowOn(<http://Dispatchers.IO|Dispatchers.IO>).catch { emit(0) }.toList()
println(list)
} while (list == listOf(1, 0))
}
ephemient
09/08/2022, 1:42 AMephemient
09/08/2022, 1:45 AM.flowOn
because with the flow and collector running in lockstep, the flow suspends when emittingNatalia Chuzhmarova
09/08/2022, 1:55 AMnetworkCallFlow
so that the resulting observed Flow never throws anything.ephemient
09/08/2022, 2:00 AMNatalia Chuzhmarova
09/08/2022, 2:03 AMephemient
09/08/2022, 2:03 AMNatalia Chuzhmarova
09/08/2022, 2:04 AM