Reputation: 159
I'm using Angular2 and I have a question about what is the best way to do if I have many observables. Can I put subscriptions inside each other or put each one in a different method and put the results in class properties?
Example :
ngOnInit() {
this.route.params**.subscribe**(params => {
if (params['id']) {
this.load = true;
this.batchService.getPagesOfCurrentObject(params['id'], "10", "0")
**.subscribe**(result => {
this.stream = result;
if (this.stream.length > 0) {
this.stream.forEach(page => { this.batchService.getPageStreamById
(page.pageId)**.subscribe**(pageStream => {
let base64 = btoa(new Uint8Array(pageStream.data)
.reduce((data, byte)
=> data + String.fromCharCode(byte), ''));
this.pages.push(base64 );
})
return;
});
}
},
error => this.errorService.setError(<any>error),
() => this.load = false
);
}
});
try {
this.customer = this.sharedService.processSelect.subscription.customer;
} catch (err) {
return;
}
}
Upvotes: 4
Views: 4498
Reputation: 2583
Having multiple observables is totally fine, this is what reactive programming is about :)
But here your problem is having too much subscribe
. Keep in mind that subscribe
is a way to create side effect. To have an easy to read code, you should try to use the least possible subscribe
.
Your use case is the perfect use case for the mergeMap
operator, that allows you to flatten nested observables.
Here what your code would look like
const response$ = this.route.params
.mergeMap(params => {
return this.batchService.getPagesOfCurrentObject(params['id'])
})
.mergeMap(stream => {
return Rx.Observable.merge(stream.map(page => this.batchService.getPageStreamById(page.pageId))
})
.map(pageStream => /* do your stuff with pageStream, base64 ... */)
response$.subscribe(pageStreamData => pages.push(pageStreamData))
See how there is a single subscription that triggers the side-effect that will modify your app's state
Note that I voluntarily simplified the code (removed error handling and checks) for you to get the idea of how to do that.
I hope it will help you thinking in reactive programming :)
Upvotes: 5