Reputation: 40896
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 concat
operator of RxJS observables. The twist is that the onNext
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:
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.
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 age
property. Obviously this becomes impractical when the results have the same shape.
Get rid of the concat
operator altogether; subscribe to subscription2
in the onComplete
handler of subscription1
. 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});
subscription1.subscribe(
data=> this.handlerOne(data),
error=>{},
()=> {
subscription2.subscribe(
data=>this.handlerTwo(data),
error=>{},
()=>console.log('All subscriptions completed!')
)
}
);
So my question: When using Observable.concat
to subscribe to several observables in sequence, how can my onNext
handler determine where the data came from? Alternatively, is there another operator I should be using for this purpose? I cannot use the forkJoin
operator because the order in which the subscriptions are completed is important.
Upvotes: 3
Views: 3636
Reputation: 23512
You could map
the 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 = 2; return person };
Then you can easily determine where it comes from:
Observable.concat(subscription1, subscription2).subscribe(
data=> { if (data.source == 1) /* do whatever */ }
);
Upvotes: 3