Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava2 passing data through flatMap on a Single

Tags:

java

rx-java2

In rxjava 1 there Observable had this flatmap method

public final Observable flatMap(Func1 collectionSelector, Func2 resultSelector)

That allowed you to pass/combine the initial result to the flatmap subscriber.

How can I achieve the same result with RxJava2?

I have a Single that emits A, I need to get B based on A and then use both A and B to perform an action.

like image 444
gdogaru Avatar asked Mar 09 '17 13:03

gdogaru


3 Answers

You have the same method on RxJava2, both on Observable and Flowable ,
but, in both RxJava1 and 2, there is no such operator for Single, you can transform Single to Observable and then apply this operators.

like image 183
yosriz Avatar answered Oct 20 '22 00:10

yosriz


Have you tried CombineLatest (http://reactivex.io/documentation/operators/combinelatest.html)

Basically you can emit A and B and then return another object based on the function result:

RXJava1

Observable
  .combineLatest([Add here your A observable],
                 [Add here your B observable],
                 new Func2<A, B, Result>() {
                    @Override
                    public Result call(A a, B b) {
                        //Do your stuff here combining both results and return the result expected
                    }
                 })

RXJava2

Observable
  .combineLatest([Add here your A observable],
                 [Add here your B observable],
                 new BiFunction<A, B, Result>() {
                    @Override
                    public Result apply(A a, B b) throws Exception {
                        //Do your stuff here combining both results and return the result expected
                    }
                 })
like image 33
Pedro Okawa Avatar answered Oct 19 '22 22:10

Pedro Okawa


The answer by Yosriz is correct but to add a code example:

Assuming the following:

class A {}

class B {}

class AB {
    private final A a;
    private final B b;

    AB(A a, B b) {
        this.a = a;
        this.b = b;
    }
}

interface AbRepository {

    Single<A> getA();

    Single<B> getB(A a);
}

Note that the method getB requires an A as a parameter.

Then you can do:

abRepository.getA()
        .toObservable()
        .flatMap(new Function<A, ObservableSource<B>>() {
            @Override
            public ObservableSource<B> apply(A a) throws Exception {
                return abRepository.getB(a)
                        .toObservable();
            }
        }, new BiFunction<A, B, AB>() {
            @Override
            public AB apply(A a, B b) throws Exception {
                return new AB(a, b);
            }
        })
        .firstOrError();
like image 35
David Rawson Avatar answered Oct 19 '22 22:10

David Rawson