necati
08/22/2019, 3:03 PMval myFlow = flow {
emit(myRepository.suspendFunctionReturnsAValue())
}
Is there any built-in way to do this better than that such as myRepository.suspendFunctionReturnsAValue().asFlow()
streetsofboston
08/22/2019, 3:12 PMmyRepository.suspendFunctionReturnsAValue()
just returns a plain value.
You could do something like this instead:
suspend { myRepository.suspendFunctionReturnsAValue() }.asFlow()
and define the asFlow
extension function yourself:
fun <T> (suspend () -> T).asFlow(): Flow<T> = flow { this() }
However, this seems more verbose than the one you try to avoid….Dominaezzz
08/22/2019, 3:19 PMmyRepository::suspendFunctionReturnsAValue.asFlow()
streetsofboston
08/22/2019, 3:27 PM::
) if the suspendFunctionReturnsAValue
is a function that takes one or more parameters….louiscad
08/22/2019, 3:31 PMFlow
?necati
08/22/2019, 3:48 PMDominaezzz
08/22/2019, 4:04 PMFlow
is the tool you need for this.coroutineScope
and async
?necati
08/22/2019, 4:09 PMFlow
adapter for Retrofit is also a method of course.Dominaezzz
08/22/2019, 4:18 PMfun <T> singleFlow(block: suspend () -> T) = flow { emit(block()) }
then do singleFlow { myRepository.suspendFunctionReturnsAValue() }
.Pablichjenkov
08/22/2019, 8:59 PMfun <T> Call<T>.asFlow(): Flow<T> = flow {
val resp = execute()
if (resp.isSuccessful) {
when( val respBody = resp.body() ) {
null -> { throw HttpNullBodyException("Unexpected Null Body") }
else -> {
emit(respBody)
}
}
} else {
val errorInfo = resp.errorBody()?.string() ?: "errorBody empty"
throw HttpCodeException(resp.code(), errorInfo)
}
}
I first had tried Dominic approach but it forced me to place a boilerplate catch()
operator after every retrofit call to map to the CustomHttpException in case of request failure.
The same cause forced my ::retrofitFunct.asFlow()
to return a Flow<Resp<T>> and not a Flow<T> which is cleaner.
Is worth mentioning that above custom exceptions extends from RuntimeException due to an issue with RxJava1 not propagating CheckedExceptions thrown from onNext()
to onError()
but rather crashing the app.streetsofboston
08/22/2019, 9:12 PMFlow<T>
to just emit a single value of type T
.
Just use a suspend someFunction(....): T
instead in that case.
`Flow`s are like suspend
functions, with respect to how they both handle Structured Concurrency and by the fact that they both produce (a) value(s) in a ‘cold’ way (‘cold’ vs ‘hot’ streams). Their difference is that a Flow
produces multiple values, and a suspend
function produces only one.