Issue
New to rxjs, looking for a good clean way to chain some observables/subscriptions.
Here's some simple pseudocode I made to try to emulate what I'm trying to do.
class Baker implements OnInit {
//functions, constructor, varibles, etc.
ngOnInit(): void {
this.myFridgeService.getDough().pipe(
switchMap(dough => {
return of(this.addToBowl(dough));
}),
switchMap(bowl => {
this.myPantryService.getMnMs()
.subscribe((mnms: Candy[]) => {
this.bagOfMnMs = mnms; // will use later
return of(mnms).pipe(filter(mnm => mnm.isGreen()));
});
}),
switchMap(greenOnes => {
return this.myMixerService.mix(bowl, greenOnes); // can I get bowl here somehow?
}))
.subscribe(cookie => {
this.bake(cookie);
},
(error: HttpErrorResponse) => {
console.error(error);
this.serviceError = error;
}
);
}
}
I can't get bowl into myMixerService because it's from a previous switchMap, and as far as I know I can't pass along multiple returns.
I could put the myMixerService call into the subscription event of myPantryService, which would look something like this
class Baker implements OnInit {
ngOnInit(): void {
this.myFridgeService.getDough().pipe(
switchMap(dough => {
return of(this.addToBowl(dough));
}),
switchMap(bowl => {
this.myPantryService.getMnMs()
.subscribe((mnms: Candy[]) => {
this.bagOfMnMs = mnms; // will use later
const greenOnes = of(mnms).pipe(filter(mnm => mnm.isGreen()));
return this.myMixerService.mix(bowl, greenOnes);
},
(error: HttpErrorResponse) => {
console.error(error);
this.serviceError = error;
});
})
).subscribe(cookie => {
this.bake(cookie);
},
(error: HttpErrorResponse) => {
console.error(error);
this.serviceError = error;
}
);
}
}
But I feel like putting that service call in a subscription event is an antipattern, and in fact part of the reason for switchMap in the first place. And that's besides the fact that it never returns back up to cookie
Solution
If you take any observable
and you subscribe
to it, you get back a subscription
. Subscriptions are not observables and cannot be turned into observable. So subscribing is a terminal operation. After you subscribe, you're done (sort of)
In short, subscribing within a switchMap
runs counter to what you require.
Here's how I might re-write your psudo-code into something that should compile
(assuming I've read your code properly)
this.myFridgeService.getDough().pipe(
map(dough => this.addToBowl(dough)),
switchMap(bowl =>
this.myPantryService.getMnMs<Candy[]>().pipe(
tap(mnms => this.bagOfMnMs = mnms), // will use later
map(mnms => mnms.filter(mnm => mnm.isGreen())),
map(greenOnes => [bowl, greenOnes])
)
),
switchMap(([bowl, greenOnes]) =>
this.myMixerService.mix(bowl, greenOnes)
)
).subscribe({
next: cookie => this.bake(cookie),
error: e => {
console.error(e);
this.serviceError = e;
},
complete: () => console.log("Done Baking cookies")
});
Answered By - Mrk Sef
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.