https://kotlinlang.org logo
#android
Title
# android
p

Pablichjenkov

08/13/2019, 8:14 PM
Is out there any Retrofit CallAdapter that returns
Flow<T>
. Is it a bad design?
j

jw

08/13/2019, 8:14 PM
Why do you want this over
suspend fun
?
☝️ 5
p

Pablichjenkov

08/13/2019, 8:16 PM
Just for symmetry with Rx. I am thinking on Rx1 migration to Flow. I am most likely conceptually wrong trying to equate Observable and Flow.
j

jw

08/13/2019, 8:17 PM
They are equivalent, but
Observable
is also somewhat incorrect for representing a network request. RxJava 2 fixed this with the
Single
type.
p

Pablichjenkov

08/13/2019, 8:25 PM
for a network request thats right.. However, in other scenarios some of my streams emit more than one event, like
State.Loading
,
State.Data
. What I normally do is having an Interactor/Actor chaining the Observables. I would like to do the same with Flow.
suspend
works is just that the chain does not look the same. My knowledge on coroutines is entry level, there is probably a better way.
j

jw

08/13/2019, 8:26 PM
Sure but Retrofit models only the network request part. You can convert
Single
to
Observable
where necessary and
suspend fun
integrates into
Flow
operators as well.
p

Pablichjenkov

08/13/2019, 8:29 PM
and
suspend fun
integrates into
Flow
operators as well
Definitely a good approach, I haven’t tried. Thanks!
g

gildor

08/13/2019, 11:19 PM
You even can easily convert suspend function to flow directly (like Single -> Observable), so it will be lazy, if you want:
Copy code
::someFunction.asFlow()
p

Pablichjenkov

08/13/2019, 11:52 PM
Thanks for replying. You mean ::someSuspendFunction.asFlow right? I still have a question either calling the
retrofitApi.suspendingFunc()
from an enclosing Flow or
retrofitApi::suspendingFunc().asFlow()
. If I want to propagate a custom CustomHttpException or CustomIOException down the stream. Should I enclose the retrofit api suspended call in a try/catch block, or append a .catch() operator after the Flow? With Observables I use .onErrorReturn() operator to intercept erros.
g

gildor

08/14/2019, 12:27 AM
You mean ::someSuspendFunction.asFlow right?
It works for suspend and common functions
p

Pablichjenkov

08/14/2019, 12:27 AM
I just saw another scenario to convert to Flow, is when refactoring a zip operator. Is easier to wrap every retrofit api call in a Flow and keep the same code just replacing Observable.zip by Flow.zip than dealing with suspend functions+asyncBuilder+await+exception
g

gildor

08/14/2019, 12:30 AM
retrofitApi.suspendFunc().asFlow() is incorrect, it should be
retrofitApi::suspendFunc.asFlow()
or
suspend { retrofitApi.suspendFunc(param) }.asFlow()
If you just want to migrate existing Retrofit service with Observable, Flow is fine, but refactor code to use suspend functions for Network requests is much more clear and less error prone in most cases
👍 1
p

Pablichjenkov

08/14/2019, 12:57 AM
Oh ok, thanks for the clarification on
.asFlow()
usage. I just corrected my post so it does not confuse any reader. I see the point, I will move into that direction then.
g

gildor

08/14/2019, 1:35 AM
retrofitApi::suspendingFunc().asFlow()
is still not correct, goal here is to convert method reference to flow, so when terminal operator will be called this method reference will be invoked by Flow chain
2 Views