'wait for API call or subscription to finish/return before calling other subscriptions (await)
I am getting a bunch of failed API calls in the network tab in chrome. This is because I can see on the waterfall that my "create customer" subscription hasn't finished its execution yet, then "create address" and "create contact phone number" both run and don't wait for it to finish.
I have looked for answers using the await....toPromise() function, but that is now deprecated and doesn't work in my scenario.
How would I implement this in newer versions of rxjs/angular?
// API call for create customer
this.userService.createCustomer(customer).subscribe({
next: (customerResult: Customer) => {
const createContactAddress =
customerAddress !== undefined
? this.userService.createContactAddress(
customerResult.partyNumber,
customerAddress.toJson()
)
: of(undefined);
const createContactEmail =
email !== undefined
? this.userService.createContactPhoneEmail(
customerResult.partyNumber,
email
)
: of(undefined);
const createContactPhoneNumber =
phone !== undefined
? this.userService.createContactPhoneEmail(
customerResult.partyNumber,
phone
)
: of(undefined);
createContactAddress
.pipe(combineLatestWith(createContactEmail, createContactPhoneNumber))
.subscribe({
next: () => {
this.isSaving = false;
this.modalSaved.emit(customerResult);
},
error: () => {
this.isSaving = false;
this.closeModal();
}
});
},
error: () => {
this.isSaving = false;
this.closeModal();
}
});
}
Solution 1:[1]
You can use switchMap/mergeMap to execute the logic in subscribe instead of nested subscribe
// API call for create customer
this.userService
.createCustomer(customer)
.pipe(
switchMap((customerResult: Customer) => {
const createContactAddress =
customerAddress !== undefined
? this.userService.createContactAddress(
customerResult.partyNumber,
customerAddress.toJson()
)
: of(undefined);
const createContactEmail =
email !== undefined
? this.userService.createContactPhoneEmail(
customerResult.partyNumber,
email
)
: of(undefined);
const createContactPhoneNumber =
phone !== undefined
? this.userService.createContactPhoneEmail(
customerResult.partyNumber,
phone
)
: of(undefined);
return createContactAddress.pipe(
combineLatestWith(createContactEmail, createContactPhoneNumber)
);
})
)
.subscribe({
next: () => {
this.isSaving = false;
this.modalSaved.emit(customerResult);
},
error: () => {
this.isSaving = false;
this.closeModal();
}
});
Solution 2:[2]
What I understood is,
- you want to call
this.userService.createCustomer- After completion of [1] you want to perform these three
createContactAddress,createContactEmail,createContactPhoneNumber- After completion of [1] and [2] you want to complete the stream.
On basis of my understanding I am providing my solution
this.userService
.createCustomer(customer)
.pipe(
switchMap((customerResult: Customer) =>
forkJoin([
this.createContactAddress(customerAddress, customerResult),
this.createContactEmail(email, customerResult),
this.createContactPhoneNumber(phone, customerResult),
]).pipe(map((result) => [customerResult, ...result]))
),
catchError((err) => {
this.isSaving = false;
this.closeModal();
})
)
.subscribe({
next: (customerResult, addressResult, emailResult, phoneResult) => {
this.isSaving = false;
this.modalSaved.emit(customerResult);
},
error: () => {
this.isSaving = false;
this.closeModal();
},
});
createContactAddress(customerAddress, customerResult): Observable<any> {
return customerAddress !== undefined
? this.userService.createContactAddress(
customerResult.partyNumber,
customerAddress.toJson()
)
: of(undefined);
}
createContactEmail(email, customerResult): Observable<any> {
return email !== undefined
? this.userService.createContactPhoneEmail(
customerResult.partyNumber,
email
)
: of(undefined);
}
createContactPhoneNumber(phone, customerResult): Observable<any> {
return phone !== undefined
? this.userService.createContactPhoneEmail(
customerResult.partyNumber,
phone
)
: of(undefined);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Fan Cheung |
| Solution 2 | Saptarsi |
