Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine multiple Retrofit Observable dynamically

I have a list of Observables like so:

 List<Observable<MyObj>> listObservables = new ArrayList<Observable<MyObj>>();

I'd like to combine all Observable in a single one, I can handle it if I know the number of Observable using zip(), for example we have 3 Observable:

 Observable<MyObj1> obs1= MyRestClient.getSomeData1();
 Observable<MyObj2> obs2= MyRestClient.getSomeData2();
 Observable<MyObj3> obs3= MyRestClient.getSomeData3();

I have a wrapper obj:

class MyWrapperObj {
    private MyObj1 onj1;
    private MyObj2 onj2;
    private MyObj3 onj3;

    public MyWrapperObj(MyObj1 onj1, MyObj2 onj2, MyObj3 onj3) {
        this.onj1 = onj1;
        this.onj2 = onj2;
        this.onj3 = onj3;
    }
}

So I can combine them like so:

 Observable<MyWrapperObj> combinedObservable = Observable.zip(obs1, obs2, obs3, new Func3<MyObj1, MyObj2, MyObj3, MyWrapperObj>() {
        @Override
        public MyWrapperObj call(MyObj1 obj1, MyObj2 obj2, MyObj3 obj3) {
            return new MyWrapperObj(obj1, obj2, obj3);
        }
    });

    combinedObservable.observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribe(new Subscriber<MyWrapperObj>() {
                @Override
                public void onCompleted() {                       
                }

                @Override
                public void onError(Throwable throwable) {
                }

                @Override
                public void onNext(MyWrapperObj wrapperObj) {
                }
            });

Everything is working fine, so my problem is how to organize this combination to be for n Observable?

RESPONSE

as @maciekjanusz mentioned in it's answer I did:

  Observable<MyWrapperObj> combinedObservable = Observable.zip(listObservables, new FuncN<MyWrapperObj>() {
        @Override
        public MyWrapperObjcall(Object... args) {
            return null;
        }
    });
like image 758
Choletski Avatar asked Oct 04 '16 12:10

Choletski


2 Answers

If you want to zip n Observables, put them in a list and apply the public static <R> Observable<R> zip(@NotNull java.lang.Iterable<? extends Observable<?>> ws, rx.functions.FuncN<? extends R> zipFunction) factory method.

List<Observable<String>> observables = Arrays.asList(Observable.just("String 1"), Observable.just("String 2"));

Observable.zip(observables, args -> {
    // put your zipping code here
});

For example, if you want to create a list of strings for each emission from all observables:

Observable.zip(observables, Arrays::asList);

Or, if using RxJava on android without retrolambda:

Observable.zip(observables, args -> Arrays.asList(args));
like image 166
maciekjanusz Avatar answered Sep 26 '22 14:09

maciekjanusz


Suppose you have the list:

List<Observable<MyObj>> listObservables

You might consider using Observable.concatDelayError

The advantage if it is finishing all Obbservable's even if any of them finishes with error (resulting in an error in such case).

Remember, that every Observable in this sequence must return the result to onNext method of Subscriber. The result also must have the same type.

Example:

Observable.concatDelayError(listObservables);
like image 34
R. Zagórski Avatar answered Sep 24 '22 14:09

R. Zagórski