Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use RxJava Observable.zip if only one Observable param is present

H,

Sorry, I'm new to RxJava and having a question about how to use rx.Observable.

Here is my code

final Observable<SomeData> data1 =
         getData(...);
final Observable<SomeData> data2 =
         getData(...);                    
final Observable<SomeData> data3 =
         getData(...);

            return Observable.zip(
                    data1,
                    data2,
                    data3,
                    new Func3<SomeData, SomeData, SomeData, SomeData>() {
                        @Override
                        public SomeData call(
                                final SomeData d1,
                                final SomeData d2,
                                final SomeData d3) {
                            //do something and return SomeData
                        }
                    });

Here I use zip when all the data are present.

My question is that if data2 and data3 are not present (i.e., they are both null), I don't/shouldn't use Observable.zip to emit the function and get the returned value, so how should I do when I only have data1? Which API should I use if I take only one parameter (data1)? Also I will have to return SomeData instead of an Observable from the function.

Any help will be much appreciated!

like image 679
Green Ho Avatar asked Nov 09 '22 06:11

Green Ho


2 Answers

You can't really apply the same 3 argument function when you only have data for the first argument but you may use a sentinel value to tell the function there is no data for parameter 2 and 3:

static final SomeData NOT_PRESENT = new SomeData(null, ...); 

void Observable<OutputType> process(Observable<SomeData> data1,
       Observable<SomeData> data2, Observable<SomeDatat> data3) {
    Func3<SomeData, SomeData, SomeData, OutputType> f3 = (a, b, c) -> {

        if (b == NOT_PRESENT) {
        }
        // process the data and return an OutputType
        return ...
    };

    if (data2 != null && data3 != null) {
        return Observable.zip(data1, data2, data3, f3);
    }

    return data1.map(v -> f3.call(v, NOT_PRESENT, NOT_PRESENT));
}
like image 127
akarnokd Avatar answered Nov 15 '22 06:11

akarnokd


You can use Observable.combineLatest() instead of zip() and add .startWith() to Observables that can be "null" not emit anything. So in your case it would be like:

Observable.combineLatest(
    data1, 
    data2.startWith(/*some value*/),
    data3.startWith(/*some value*/),
    new Func3<SomeData, SomeData, SomeData, SomeData>() {
        @Override
        public SomeData call(
            final SomeData d1,
            final SomeData d2,
            final SomeData d3) {
                //do something and return SomeData
        }
    });
like image 27
borichellow Avatar answered Nov 15 '22 05:11

borichellow