0

In the below example, foo receives data from bar yet ignores when bar completes. foo is completed when baz completes, which is not the behavior I desire.

var baz = Rx.Observable.interval( 50 ).take( 10 );

var foo = baz
    .select(function (x) { 
        var bar = Rx.Observable.range(x, 3);
        return bar;
    })
    .switch();

Is there a variant of switch or a technique that I could use to have the newly created foo observable have the same lifetime as bar? That is, I would like foo to complete in the event that bar completes.


Solution:

var baz = Rx.Observable.interval( 50 ).take( 10 );

var foo = baz
    .select(function (x) { 
        var bar = Rx.Observable.range(x, 3).materialize()
        return bar;
    })
    .switch()
    .dematerialize();
Jeff
  • 623
  • 3
  • 8
  • 22

1 Answers1

3

onCompleted() is by definition a terminal case so no you cannot receive onCompleted() directly in the outer Observable.

You have a couple options depending on how you need to use the onCompleted.

Either you could use .tapOnCompleted() or .finally() to handle a side effect of stream termination:

var foo = Rx.Observable.range(0, 3)
.select(function (x) { 
    return Rx.Observable.range(x, 3)
           .tapOnCompleted(function(){/*Apply side effect*/});
          //Or .finally()

})
.switch();

Or you will need to materialize the inner stream to handle the values:

var foo = Rx.Observable.range(0, 3)
.select(function (x) { 
    var bar = Rx.Observable.range(x, 3)
    .materialize();
    return bar;
})

.switch()

foo.subscribe(function(x) {
  if (x.kind == 'N') {
    process(x.value);
  } else if (x.kind == 'C') { /*Do something else*/}
});

Note that in the example you gave when the switch occurs the Observable will not complete, only the last one will complete, because subsequent values are coming in too fast.

If all of the sequences should be running until completed you should use concatAll() instead of switch()

paulpdaniels
  • 18,395
  • 2
  • 51
  • 55
  • I'm modified the example so hopefully it's a bit more clear. I'm really surprised there is no operator for what I want to achieve. RxJS doesn't have materialize, or that would work. – Jeff Aug 14 '15 at 16:55