RxJava chaine of consecutive operations - android

I am a newbie in RxJava. I want to combine three consecutive asynchronous operations in to chain by RxJava2:
fun getDataFromRESTApi(): Observable<TheData>
saveDataToCache(theData: TheData): Completable
getDataFromCache(): Observable<TheData>
How can I do this? What rxjava methods I could to use?

I'm not sure what you trying to achieve exactly but there's the concatMap operator :
getDataFromRESTApi()
.concatMap(theData -> saveDataToCache(theData).toObservable())
.concatMap(cachedData -> getDataFromCache()) //maybe not needed
In the other hand if saveDataToCache returns the saved data (cached) you don't need the third line.

Related

android app Using Flow/coroutine on top of Rxjava2

I want to use coroutine in my kotlin app for must of it. but this app depends a lot on a service which return rxjava2 type object (so our input will be all the rxjava type). How can we still use coroutine in this model app instead of rxjava2. should we create a layer only convert rxjava object to normal object (or coroutine object?). or can we use both two together like:
SomeObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { value->
viewmodelScope.launch{
// send a flow or coroutine suspend fonction with value
}
},
Thanks,
You could wrap the RxJava functions with suspend functions.
See https://github.com/Kotlin/kotlinx.coroutines/issues/869
I want to answer my own question, It's not a good approche to use flow and rx at the same time. because it resolves the same problem. Rxjava + livedata is a clean architecture to go. or just use flow. so for resume:
Rxjava + livedata (a little bit coroutine to do some general
operation)
flow + coroutine
Two clean ways to make a good architecture. so if I have already rx type there is no need to convert to flow and reuse.

Chaining N dependant observables

I'm quite new to reactive programming and I've introduced myself to RxJava2 in Android. For the time being, I've faced easy problems, such as zipping observables. But now, something new cropped up, I'm trying to explain.
Suppose I've got a list of requests Observable<List<Request>>. What I want to do is to call a web service which returns per each request, the list of routes (wrapped in an Observable). I've checked questions like this, but in this case I think I can't flatMap an observable and a list of observables.
How can I do it? Is there any other operator?
You can flatten the Observable<List<Request>> into Observable<Request> using flatMapIterable. Assuming you have a helper method with the signature Observable<List<Route>> getListOfRoutes(Request request) { ... } you can do this:
Observable<List<Request>> obs = ...;
obs.flatMapIterable(l -> l)
.flatMap(request -> getListOfRoutes(request)
.doOnNext(routes -> request.setRoutes(routes))
.map(ign -> request)
)
...
This is assuming that you ultimately want Observable<Request> to be emitted downstream. If you want a different type, you can do something different in the map operator to suit your needs.

RxJava2 and Android complex observable chaining

I have been working with Rx Java 2 for awhile but recently came across a situation that has stumped me. I have a semi-complex chain of operations and wish to pass a "state object" down the chain.
There are 4 operations during which I wish to repeat operations 2 and 3 (serialy, not together) until certain conditions are true. I know i can solve this by chaining each operation using andThen(), but this limits my ability to pass a state object down the chain without reaching outside of the chain.
The reason I need to have a state object is because I need to save an initial value during the first operation and compare it to a value recieved during operation 4 to determine if the overall procedure was successful.
Any clues as to what RxJava2 operators can help me achieve the proper repeat conditions for operation 2 and 3? I would prefer to not nest observables if possible.
You can keep your state as some AtomicReference<State> and use repeatUntil operator.
AtomicReference<State> state = new AtomicReference<>();
Completable operation = Completable.create() // do something and modify state
.repeatUntil(() -> state.get() == SATISFYING_CONDITION);
You can easily chain these Completables with andThen

Calling RXJava2 Completable in a cascade

Usually to implement cascading tasks we use flatMap .
Like ObserableA.flatMap(A->ObserableB)
However I have a situation in which I would want to have two Completables that are interdependent.
Completable OperationA;
Completable OperationB;
I need OperationB to only execute after Operation A. Since there are no flatmap operators in Completable , how should I go about the situation?
You can use the andThen operator from the first Completable.
http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Completable.html#andThen-io.reactivex.CompletableSource-

RxJava1 concatMap cause MissingBackpressureException

I am trying to transform Observable using concatMap, since the order is important for my case.
#Test
fun load_data() {
val sub = TestSubscriber<Long>()
var s = BehaviorSubject.create<Long>()
s.concatMap {
Observable.timer(it, TimeUnit.MILLISECONDS)
}
.take(4)
.subscribe(sub)
s.onNext(5)
s.onNext(6)
s.onNext(7)
s.onNext(8) //rx.exceptions.MissingBackpressureException
sub.awaitTerminalEvent(500, TimeUnit.MILLISECONDS)
sub.assertNoErrors()
}
I have changed real data loading to Observable.timer() in order to simplify example and make it easier to reproduce.
I am using in the app BehaviorSubject to link UI actions with rx
From documentation, especially from marble diagram I expect that it will store items in queue and transform them one-by-one.
However it seems like concatMap has queue with size set only to 2 items. Adding more items cause MissingBackpressureException
So I have following questions:
Why concatMap has queue size 2 instead of RxRingBuffer.SIZE as
other operators has?
Should I as a rule add any of onBackpressure* operators before
calling concatMap to prevent from MissingBackpressureException
exception?
Before I answer the questions, please consider switching to RxJava 2 where this is be not a problem with an Observable.
Why concatMap has queue size 2 instead of RxRingBuffer.SIZE as other operators has?
The operator runs one Observable at a time and there was no reason to prefetch more than 1 in advance.
Should I as a rule add any of onBackpressure* operators before calling concatMap to prevent from MissingBackpressureException exception?
Yes.

Categories

Resources