I'm currently looking into RxJS's .merge however I'll also ask the question here as I find explanations here at times to be brilliant.
Okay, I have a form that depending on user input opens a modal window, I subscribe to the modal close event and pass back some data that I will use after I call / subscribe to a service method to retrieve some data, then when this has happened I do the same again and call / subscribe another service method to update some date then when this has finished I run a local method. So what I have here is 3 nested .subscribe
s
const dialogRef = this.matDialog.open(ModalWindowComponent, {});
let userId = 4; // this is the real world is selected by the user
let userData = {}; // this is actually form data created by the user
// dialog is closed
dialogRef.afterClosed().subscribe((result) => {
if (typeof result === 'string') {
// subscribe to a service to get some data
this.userService.getUser(userId).subscribe((user: any) => {
// do something with the data
let mergedObj = Object.assign({}, user, {newProperty: result});
// subscribe to another service to update the data
this.scbasService.updateUser(userId, mergedObj).subscribe(() => {
this.doSomethingElse(userData);
});
});
}
});
What I have here is a "pyramid of doom". I remember when working with AngularJS and working with promises I could return the next service and have chained .then()
s. I really want to flatten my code, any ideas?
How could I do the same here so my code doesn't indent constantly?
If I haven't asked or explained myself so well please say so and I will rephrase my question.
You could do something like this:
filter
so that onlystring
results are processed.mergeMap
to compose an inner observable for thegetUser
andupdateUser
calls.mergeMap
again to merge the inner observable into the outer observable.do
to do something after the user is updated.subscribe
. Otherwise, nothing will happen.Something to keep in mind is that nesting
subscribe
calls withinsubscribe
calls is an antipattern.If you want, you could flatten it further, using the result selector in the first
mergeMap
to add the property: