3

Example 1:

var obsNumber = /* observable that produce numbers */;
var obsText1 = /* observable that produce text */;
var obsText2 = /* observable that produce text */;
var obsContext = /* IF obsNumber < 5 THEN obsText1 ELSE obsText2 */;

obsContext is an observable that will return either data from obsText1 or obsText2, depending on the value of obsNumber.

Example 2:

var arrOfObservables = /* an array of observables */;
var obsNumber = /* observable that produce numbers */;
var obsSelect = /* arrOfObservables[obsNumber] */;

obsSelect is an observable, that will return data from the selected observable from the arrOfObservables array determined by the value produced by obsNumber.

I cannot figure out how to specify this behavior using RxJS. It seems to me I need to be able to subscribe/unsubscribe dynamically between multiple observables.

How to make the two examples work using RxJS?

Gajus
  • 69,002
  • 70
  • 275
  • 438
Egil Hansen
  • 15,028
  • 8
  • 37
  • 54

1 Answers1

5

Use switch:

Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence.

Example 1

var obsNumber,
    obsText1,
    obsText2;

obsNumber = Rx.Observable.interval(500).take(10);
obsText1 = Rx.Observable.return('a');
obsText2 = Rx.Observable.return('b');

   obsNumber
    .do(function (x) {
        console.log('x: ' + x);
    })
    .map(function (x) {
        return x < 5 ? obsText1 : obsText2;
    })
    .switch()
    .subscribe(function (context) {
        console.log('context: ' + context);
    });
<script src='https://rawgit.com/Reactive-Extensions/RxJS/v.2.5.3/dist/rx.all.js'></script>

Example 2

var obsNumber,
    arrOfObservables;

obsNumber = Rx.Observable.range(0, 3);

arrOfObservables = [
    Rx.Observable.return('a'),
    Rx.Observable.return('b'),
    Rx.Observable.return('c')
];

obsNumber
    .do(function (x) {
        console.log('x: ' + x);
    })
    .map(function (x) {
        return arrOfObservables[x];
    })
    .switch()
    .subscribe(function (context) {
        console.log('context: ' + context);
    });
<script src='https://rawgit.com/Reactive-Extensions/RxJS/v.2.5.3/dist/rx.all.js'></script>
Gajus
  • 69,002
  • 70
  • 275
  • 438
Brandon
  • 38,310
  • 8
  • 82
  • 87
  • I was under the impression that you should use _selectMany_ instead of _select_ here. Does Rx automatically unwrap the Observables you return in the function given to _select_, or is that a feature of _switchLatest_? – raimohanska Jun 28 '13 at 17:27
  • 1
    @raimohanska The 3 "builtin" functions to unwrap an inner observable are `switchLatest` (keeps unsubscribing from the previous and subscribing to the new one), `concatObservable` (queues up each observable and subscribes to them in sequence) and `mergeObservable` (concurrently subscribes to them all). `selectMany` is just short-hand for `select(return an observable).mergeObservable()` – Brandon Jun 28 '13 at 18:53
  • @Brandon thanks, I wasn't actually aware of concat/mergeObservable methods. Those three together form really nice API indeed. The select and selectMany methods are a bit poorly named though, in my opinion. – raimohanska Jun 29 '13 at 08:42