Paul Woitaschek
07/17/2019, 1:58 PMFlow<ViewState>
. This ViewState
also has a boolean property if an error should be shown.
Upon error I want to emit the latest view state but call copy(showError = true)
and complete the flow so that a consumer can use sth like:
.repeatWhen { repeatClickedFlow() }
streetsofboston
07/17/2019, 2:00 PMPaul Woitaschek
07/17/2019, 2:02 PMstreetsofboston
07/17/2019, 2:06 PMcontentFlow
when the first one produces an error/exception?Paul Woitaschek
07/17/2019, 2:07 PMstreetsofboston
07/17/2019, 2:09 PMemitAll
inside a try-catch clause.
In the catch, get the contentFlow again (i would change the type of contentFlow
from Flow<...>
into () -> Flow<...>
, and use contentFlow()
to actual obtain the flow.Paul Woitaschek
07/17/2019, 2:10 PMstreetsofboston
07/17/2019, 2:12 PM...
return flow {
var latestState = baseState
emit(latestState)
while (true) {
val sourceFlow = contentFlow()
try {
sourceFlow.collect {
latestState = it
emit(latesState)
}
} catch (t: Throwable) {
latestState = latestState.copy(....)
emit(latestState)
}
}
}
Something like this….streetsofboston
07/17/2019, 2:15 PMcontentFlow()
, I assume you would need to create/get a brand-new one. If not, if just starting to collect
it again is enough, just use contentFlow.collect
instead of the `sourceFlow.connect`…streetsofboston
07/17/2019, 2:18 PMcontentFlow.share(1)
and use this shared-flow to collect and use it in the onErrorResumeNext(...)
as well. But Flow<T>.share(n)
does not yet exist…..Paul Woitaschek
07/17/2019, 2:33 PMstreetsofboston
07/17/2019, 2:34 PMPaul Woitaschek
07/17/2019, 2:34 PMstreetsofboston
07/17/2019, 2:37 PMPaul Woitaschek
07/17/2019, 2:37 PMstreetsofboston
07/17/2019, 2:38 PMPaul Woitaschek
07/17/2019, 2:38 PMstreetsofboston
07/17/2019, 2:40 PMstreetsofboston
07/17/2019, 2:42 PMPaul Woitaschek
07/17/2019, 2:43 PMstreetsofboston
07/17/2019, 2:43 PMstreetsofboston
07/17/2019, 2:46 PM...
fun viewState(repeat: Flow<Unit>): Flow<ViewState> {
val initialState = ViewState(content = null, loading = true, showError = false)
return flow {
emit(initialState)
var lastState = initialState
suspend fun updateAndEmit(update: ViewState.() -> ViewState) {
lastState = update(lastState)
emit(lastState)
}
repeat.startContentFlow(::updateAndEmit)
}
}
suspend fun <T> Flow<T>.startContentFlow(updateAndEmit: suspend (ViewState.() -> ViewState) ->Unit) {
try {
contentFlow().collect {
updateAndEmit { copy(content = it, loading = false) }
}
} catch (t: IOException) {
updateAndEmit { copy(loading = false, showError = true) }
take(1).collect {
updateAndEmit { copy(loading = true, showError = false) }
startContentFlow(updateAndEmit)
}
}
}
...
streetsofboston
07/17/2019, 2:49 PMPaul Woitaschek
07/17/2019, 2:50 PMstreetsofboston
07/17/2019, 2:51 PMshare
or cache
methods on Flows… that is coming thoughstreetsofboston
07/17/2019, 2:53 PMPaul Woitaschek
07/17/2019, 2:53 PMstreetsofboston
07/17/2019, 2:58 PMtake(1)
is a Flow that terminates after emitting 1 item. Try to just move the startContentFlow(updateAndEmit)
call outside of that collect { .. }
blockstreetsofboston
07/17/2019, 2:59 PMstartContentFlow(updateAndEmit)
call and just wrap the body of startContentFlow
inside a while(true) { ... }
loopPaul Woitaschek
07/17/2019, 3:22 PM