Flow/Coroutines question: I'm trying to migrate fr...
# coroutines
a
Flow/Coroutines question: I'm trying to migrate from RxJava to Flow for Android apps. I often write apps where in some starting point of the app (onCreate or the ViewModel init function for example) I subscribe to a bunch of observables. So, a typical
init
of a view model of mine may look like this:
Copy code
init {
    myObservable
        .filter { whatever() }
        .map { whatever() }
        .subscribe { pushToMySubject() }

    myOtherObservable
        .filter { whatever() }
        .map { whatever() }
        .subscribe { pushToMyOtherSubject() }

    myThirdObservable
        .filter { whatever() }
        .map { whatever() }
        .subscribe { pushToMyThirdSubject() }
}
But when using flow, we can only call
collect
(which if I'm not mistaken is analagous to
subscribe
in RxJava) from within a coroutine context, which makes sense. But, as far as I can tell, calling
collect
blocks that coroutine context (my terminology might be garbage here) so you can't really have the above setup because we wouldn't execute the last two subscribes until the first observable completes. So two questions: 1. Is my understanding correct? 2. What's the preferred path to handle this sort of scenario?
o
are these intended to live beyond
init
?
a
yes
Again this is getting into Android specifics, but there's a coroutine context scoped to the viewmodels lifecycle that the Android APIs expose
o
I think the correct method here is
viewModelScope.launch
a
yeah that's what I'm using
o
you would
launch
for each thing you want to collect
a
Got it - so for the above flow, we'd want three different calls to
launch
o
yea
a
word. Thank you!
d
You can also call
.launchIn(viewModelScope)
on the flow itself.
☝️ 2
a
Awesome tip, thanks Dominic!
a
So if you use
launchIn
you really need to use
onEach
or some other side effect operator to actually process your items. Interesting.
e
Yes. It is just a DSL. Instead of
Copy code
compositeDisposable.add(..... .subscribe { ... })
you do
Copy code
.... .onEach { ... }.launchIn(scope)
You use
scope
instead of
compositeDisposable
to track subscriptions and make sure they are closed.