Search code examples
reactive-programmingrxjsreactive-extensions-js

Transform an observable sequence into an observable sequence producing values only from the most recent observable sequence


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?


Solution

  • 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>