Flows
A call also comes as a cold Flow<CallStatus<S, F>>, for the UI that wants the Loading state as an emission rather than as a separate piece of bookkeeping.
This page covers the three builders that produce one.
| Builder | Emits |
|---|---|
|
|
|
|
|
|
flow
flow { } is call { }'s Flow form, and takes the same optional request customization as a second block:
APIServices.articles(client)
.flow { Articles().get(page = 1) }
.collect { status ->
when (status) {
CallStatus.Loading -> println("Loading…")
is CallStatus.Success -> println(status.success)
is CallStatus.Failure -> println("Failed: $status")
}
}
The three branches above are exhaustive: Loading is the only state that is neither a Success nor a Failure.
Every one of these flows is cold. Nothing is called until the flow is collected, and each collection calls again, so a retry is simply another collection.
callFlow
callFlow { } is the same wrapper over anything that answers a CallStatus.Result, not just a single endpoint call.
A repository function that already folds several calls together is one example:
class ArticleRepository(private val articles: ServiceCaller<ArticlesService>) {
suspend fun page(page: Int): CallStatus.Result<List<ArticleSummary>?, NoFail> =
articles.call { Articles().get(page = page) }
fun pageFlow(page: Int): Flow<CallStatus<List<ArticleSummary>?, NoFail>> =
callFlow { page(page) }
}
Two operators read the states as they go by, leaving the flow untouched: onSuccess { } runs on every Success, onFailure { } on every Failure.