Reputation: 21595
Background
I am just diving into the concept of RX for java. Frankly, I don't get it. In my project I use retrofit library for calling services. Currently, I have implemented all the services using callback. If I want to orchestrate service calls I have to call callbacks in callbacks which leads to quite a confusing code.
Problem
For the following two services I would like to call service B iff service A completed successfully using the Observables approach.
public interface RetrofitRestService {
@GET("...")
Observable<Object> A();
@GET("...")
Observable<Object> B();
}
I was searching for Observable operators I could use for my task but without any luck. I can imagine an operator like this:
RetrofitRestServices service;
service.A().ifSuccessfull(B());
//OR
service.A().ifWasNotEmpty(B());
//OR
service.A().useCondition(new Condition(){ ... }, B());
Upvotes: 2
Views: 2003
Reputation: 11515
If you want to call A, then call B, you can use the operator concat
: B will be called if A is completed.
service.A().concatWith(service.B()).subscribe();
But if A return null
, B will be called.
If it's the case, then this anwser will be better : https://stackoverflow.com/a/28685808/476690
EDIT after comment
If you want to use the result of A()
then flatMap
operator is what you need
service.A().flatMap(resultOfA -> service.B(resultOfA)).subscribe();
(giving resultOfA
as an argument of B()
is just an example of use)
Another way :
You can build a result too from the response of A, and the response of B
service.A().flatMap(resultOfA -> service.B().zipWith(Observable.just(resultOfA), (a, b) -> new ResultOf(a, b))).subscribe();
zip
operator will build a result with the result of A and B, in this case. ResultOf
is just an example class to show how to build a result with the result of A and B.
More info on flapMap
: When do you use map vs flatMap in RxJava?
Upvotes: 3
Reputation: 159
What about this:
service.A().isEmpty().filter(new Func1<Boolean, Boolean>() {
@Override
public Boolean call(Boolean empty) {
return !empty;
}
})
.flatMap(new Func1<Boolean, Observable<? extends Object>>() {
@Override
public Observable<? extends Integer> call(Boolean empty) {
return B();
}
});
The isEmpty
operator will emit a boolean value, which will be true only if A() doesn't emit anything. That's why if A() emits an item, the filter checking if the result of isEmpty
will pass and the flatMap
will be invoked, thus invoking B().
Upvotes: 1