MLProgrammer-CiM
MLProgrammer-CiM

Reputation: 17257

What is RxJava equivalent of orElse

There is one common operation in stream/functional land in other languages, that's orElse(). It serves like an if, where when the current chain didn't get any result, it changes to the alternate one. In a language with Maybe types it'd basically continue the chain for a Some type or change to the orElse on a None type.

Ideal case:

Observable.just(false)
          .filter(value -> { return value; })
          .map(value -> { return 1; })
          .orElse(Observable.just(0));

Observable.<Boolean>error(new IllegalStateException("Just playing"))
          .filter(value -> { return value; })
          .map(value -> { return 1; })
          .orElse(Observable.just(0));

It can be currently reproduced using concat and takeFirst, but it's just not semantically the same, and doesn't cover error handling properly.

Observable.concat(Observable.just(false)
                            .filter(value -> { return value; })
                            .map(value -> { return 1; }), 
                  Observable.just(0))
          .takeFirst();

Upvotes: 11

Views: 2529

Answers (1)

Matt Pinkston
Matt Pinkston

Reputation: 1630

It looks like they have that, but with different naming: defaultIfEmpty or switchIfEmpty.

Observable.just(false)
        .filter(value -> value)
        .map(value -> 1)
        .defaultIfEmpty(0)
        .subscribe(val -> {
            // val == 0
        });

Observable.just(false)
        .filter(value -> value)
        .map(value -> 1)
        .switchIfEmpty(Observable.just(0))
        .subscribe(val -> {
            // val == 0
        });

// Error thrown from the first observable
Observable.<Boolean>error(new IllegalStateException("Crash!"))
        .filter(value -> value)
        .map(value -> 1)
        .switchIfEmpty(Observable.<Integer>error(new IllegalStateException("Boom!")))
        .subscribe(val -> {
            // never reached
        }, error -> {
            // error.getMessage() == "Crash!"
        });

// Error thrown from the second observable
Observable.just(false)
        .filter(value -> value)
        .map(value -> 1)
        .switchIfEmpty(Observable.<Integer>error(new IllegalStateException("Boom!")))
        .subscribe(val -> {
            // never reached
        }, error -> {
            // error.getMessage() == "Boom!"
        });

Upvotes: 12

Related Questions