2

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());
Amio.io
  • 20,677
  • 15
  • 82
  • 117

2 Answers2

3

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();

zipoperator 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?

Community
  • 1
  • 1
dwursteisen
  • 11,435
  • 2
  • 39
  • 36
  • I am going to try it this afternoon. How can I work with the result of A() and then use "concatWith"? I have to process the result of A(). If it is a longer solution please add an edit to your answer. – Amio.io Feb 24 '15 at 10:04
  • The new info looks great. I still haven't make it home. But can't wait to check it out. I believe it will work. Just one more thing... In Android we still use Java 6, no closures there. How would you write down "service.A().flatMap(resultOfA -> service.B(resultOfA)).subscribe();" in Java 6. I mean particularly "resultOfA -> ... ". – Amio.io Feb 24 '15 at 13:15
  • You can't, out of the box. But you can try retrolambda ( gradle plugin : https://github.com/evant/gradle-retrolambda ). It convert lambda to anonymous class. I used it on a small android project. But some people have some issues with it (with proguad, I presume) – dwursteisen Feb 24 '15 at 13:46
1

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().

meddle
  • 159
  • 2
  • 9
  • I am going to try it this afternoon. How can I work with the result of A() and then use "flatMap"? I have to process the result of A(). If it is a longer solution please add an edit to your answer. – Amio.io Feb 24 '15 at 10:05
  • Hmm if you need the actual result of A(), you can either cache it and then use the above logic to trigger B(), or if B uses the result of A() use the answer provided by dwursteisen. As it seem, you need something similar to the code provided by him, that's why I'm putting +1 on his answer. – meddle Feb 24 '15 at 22:28
  • Thx Meddle, your answer helped me to understand observables more. – Amio.io Feb 24 '15 at 22:33