3

I'm trying to execute two Maybe at once and call a specific method once both are done. This works if both Observables return a value but in certain cases one might not emit an item thus calling only doOnComplete and not doOnSuccess. So if one of those Maybes' doesn't call doOnSuccess the zip() block isn't executed. I'm wondering how to handle such a scenario?

Following my code (stripped down to the essential part):

private void fetchData(){
    Maybe<Integer> maybeOne = getId(); // may return Maybe.empty()
    Maybe<List<String>> maybeTwo = getList();
    Maybe.zip(maybeOne, maybeTwo, (id, list) -> {
        initView(id, list); // only called if values have been emitted
        return true;
    }).subscribe();
}

I would expect that the zip() block is always called but with null values in case the Maybe didn't call onSuccess. This isn't the case so can I handle such a scenario?

user3420815
  • 775
  • 9
  • 20

1 Answers1

9

You can use the materialize operator. It basically transforms the serial invocation into object (wrapped inside a Notification object).

Observable.zip(maybeOne.toObservable().materialize(),
                maybeTwo.toObservable().materialize(), (id, list) -> {
                    Log.d(TAG, "zip completed");
                    return true;
                }).subscribe();

Now your zip will always "finish", but your real data can be retrieved using:

id.getValue()

And if your maybe is Maybe.empty() then it will not return the value, but null.

GVillani82
  • 17,196
  • 30
  • 105
  • 172
  • 2
    Excellent, this feels much more clean than explicitly wrapping all the objects in `Optional` or creating "empty" instances to compare with, which are the other two solutions I've seen for this problem. It feels a little verbose that you have to call `toObservable().materialize()` on every input stream, but I guess if you do this in many places you can write your own `zipAlways(Maybe, Maybe, NullableParamFunction)`. – Thorbear Mar 23 '18 at 08:51
  • 2
    I got a warning saying `materialize` is marked unstable. – Rod Apr 22 '20 at 16:18