Patrick Patrick - 4 months ago 37x
AngularJS Question

RxJS Observable.concat: How to know where next result came from?

My application (Angular 2 with RxJS 5 written in TypeScript) requires me to make 2 calls to a web service in a predefined order. Inspired by this page I decided to try the

operator of RxJS observables. The twist is that the
callback that receives values needs to forward them to different handlers depending on where they came from

My code can be simplified to:

suscription1 = Observable.return({name:'John', age:7});
subscription2 = Observable.return({name:'Mary', color:'blue'});
Observable.concat(subscription1, subscription2).subscribe(
data=>{ /* need to know which subscripion
i'm dealing with to direct to the right handler*/}

What's the most elegant way to determine where my data came from at each observable emission? I have thought of a couple of ways but they all seem clumsy:

  1. Keep a counter in scope, perhaps as a class property. Check it and increment it each time you receive a result. Since each observable emits just once, the counter will have its initial value when the first subscription outputs and it will have initial+1 when the second outputs. Problem is this won't work when I don't know how many times each observable will emit before being complete.

  2. Inspect each result and identify its source by the result's shape. For instance, in my example only the first observable's result has an
    property. Obviously this becomes impractical when the results have the same shape.

  3. Get rid of the
    operator altogether; subscribe to
    in the
    handler of
    . This would work, but it doesn't scale well; if I have 4 or 5 subscriptions to concatenate, it becomes nested hell.

Solution 3 with just 2 subscriptions...

suscription1 = Observable.return({name:'John', age:7});
subscription2 = Observable.return({name:'Mary', age:8});
data=> this.handlerOne(data),
()=> {
()=>console.log('All subscriptions completed!')

So my question: When using
to subscribe to several observables in sequence, how can my
handler determine where the data came from? Alternatively, is there another operator I should be using for this purpose? I cannot use the
operator because the order in which the subscriptions are completed is important.


You could mapthe suscriptions to know where it's coming from.

suscription1 = Observable.return({name:'John', age:7})
         .map(person => { person.source = 1; return person };
subscription2 = Observable.return({name:'Mary', age:8})
         .map(person => { person.source = 1; return person };

Then you can easily determine where it comes from:

Observable.concat(subscription1, subscription2).subscribe(
    data=> { if (data.source == 1) /* do whatever */ }