Reputation: 111
i have to do 2 api call, i want first call to complete and then the second call to start sequentially. 2nd call dont have any dependency on first call. both the call makes update to the DB. if i use the below code, update to the second call is happening multiple times due to which it is trying update same record multiple time which i want avoid.any help is appreciated.
updateUserCommentsObservable(): Observable<any> {
if (!this.userComments) {
return EMPTY;
}
const source = this.arrayGroupBy<TrailerComparisonUserComment>(
this.userComments,
comment => comment.trailerComparisonId);
return from(Object.keys(source)).pipe(
mergeMap(x => this.trailerComparisonService.updateUserComments(
x, source[x])
)
);
}
this.updateUserCommentsObservable().pipe(
flatMap(() => from(this.trailerComparisons).pipe(
mergeMap(trailerComparison =>
this.trailerComparisonService.saveReviewComplete(
trailerComparison.trailerComparisonId))
)
)
).subscribe(() => {
this.userComments = [];
this.disableStage1Review = true;
let snackBarRef = this.snackBar.open('Well done! Stage1 Review Complete has been successfully saved.', 'Dismiss');
}, error => {
console.log("Error", error);
let snackBarRef = this.snackBar.open('Error! ' + error.error.message, 'Dismiss');
});
Upvotes: 0
Views: 2749
Reputation: 13515
You can run multiple observables sequentially using the concat
function.
concat(
obs1$,
obs2$
).subscribe(result => {
console.log(result);
});
If each observable returns 1 result and completes (an http request), then subscribe will receive 2 values - the result of obs1$
and then the result of obs2$
.
If you want to wait for both to return a result, you can use the toArray
function.
concat(
obs1$,
obs2$
).pipe(
toArray()
).subscribe(result => {
console.log(result);
});
The result in the subscribe will now be an array of obs1$
result and obs2$
result.
Your requirements are a bit more complex because you have an initial observable and then an array of observables. If you want to run your array of observables sequentially, then you can create the array of observables up front and pass them into concat.
const trailerComparisons$ = this.trailerComparisons.map(c =>
this.trailerComparisonService.saveReviewComplete(c.trailerComparisonId)
);
concat(
this.updateUserCommentsObservable(),
...trailerComparisons$
).pipe(
toArray()
).subscribe(/* subscribe handling */)
DEMO: https://stackblitz.com/edit/angular-jldrrh
Upvotes: 1
Reputation: 2951
To make calls sequential you have to use concatMap
instead of mergeMap
.
https://rxjs-dev.firebaseapp.com/api/operators/concatMap
Upvotes: 0