6
votes

I want to use Rx.Observable.if to run one of two observables should a conditional observable resolve to true or false.

What I want to achieve would look something like this:

Rx.Observable.if(conditionalObservable.map(x => x.length > 0), firstObservable, secondObservable).subscribe()

If conditionalObservable sends a next and then completes with a true value, firstObservable should be run and otherwise, secondObservable should run.

Now obviously that doesn't work because Rx.Observable.if expects a function conditional, not an observable. How can I achieve the exact same functionality in RXJS?

Note: This issue is almost the same but I don't think it's concise enough because 1) you have to have two pausable statements and 2) unless you append a take(1) to your conditional observables, you can't guarantee the conditional won't emit more next events. IMO it's a workaround and subject to much more human error.

2

2 Answers

6
votes

If I understand well, you could try something like that:

conditionalObservable.map(x => x.length > 0)
  .last()
  .flatMap(function(condition){
      return condition ? firstObservable : secondObservable});
  .subscribe()

I added the last part because you mentioned that you want to choose your observable (first or second) on the conditionalObservable last value.

I am not sure of the value of the if operator here, as it switches based on a scalar value which has to be produced synchronously by the selector function. So unless you use that function to return a variable which is accessible in a closure, and which you can modify at the point where your condition is evaluated, it is not so useful in my opinion. And even then, your selector becomes an impure function which is not a best practice for testing purposes and else.

1
votes

How about using switch?

conditionalObservable
  .map(x => x.length > 0 ? firstObservable : secondObservable)
  .switch()
  .subscribe(...)

Or flatMapLatest? If I understand the documentation well, this will do the same as the former:

conditionalObservable
  .flatMapLatest(x => x.length > 0 ? firstObservable : secondObservable)
  .subscribe(...)