I need wait for two requests (observables) and do some things. What i need:
- Wait for requests (observables) end
- If one of them failed - display one error
- If both of them failed - display second error
- If first success - do some things
- If second success - do some things
i can combine 4 and 5 if that matter for errors handling.
I tried to use forkJoin
but it fails at all if one of requests failed.
I tried to use concat
but it works the same as forkJoin
I tried to use combineLatestWith
but it doesn't display errors at all as combineLatest
Finally i tried to use next:
const firstRequest$ = this.doFirstRequest(searchRequest);
const secondRequest$ = this.doSecondRequest(searchRequest);
combineLatest([firstRequest$, secondRequest$]).subscribe(([res1, res2]) => {
console.log(res1, res2);
}, err => {
console.log(err);
});
and now i got only both success results and didn't get any error What im missing?
CodePudding user response:
catch your errors at the request level and transform them into something usable:
const firstRequest$ = this.doFirstRequest(searchRequest).pipe(
catchError(err => of(null)) // could be something other than null like {error: err} if you need the error
);
const secondRequest$ = this.doSecondRequest(searchRequest).pipe(
catchError(err => of(null))
);
forkJoin([firstRequest$, secondRequest$]).subscribe(([res1, res2]) => {
if (!res1 && !res2) {
// both failed
} else if (!res1 || !res2) {
// one failed
}
if (res1) {
// req 1 success
}
if (res2) {
// req 2 success
}
// whatever you need to do now that they're both done
}, err => {
// can't get here now
});
CodePudding user response:
You need to use
forkJoin
for this use case, See ForkJoin docs.Add
catchError
operator to the first stream to handle the first requestAdd another
catchError
operator to the second stream to handle itAdd
tap
operator to the first stream 1Add another
tap
operator to the first stream 2
const firstRequest$ = this.doFirstRequest(searchRequest).pipe(
tap(() => {
// DO SOMETHING STREAM 1 REGARDLESS OF STREAM 2
}),
catchError((e => {
console.error('Error from stream 1', e);
return EMPTY;
});
);
const secondRequest$ = this.doFirstRequest(searchRequest).pipe(
tap(() => {
// DO SOMETHING STREAM 2 REGARDLESS OF STREAM 1
}),
catchError((e => {
console.error('Error from stream 2', e);
return EMPTY;
});
);
forkJoin([firstRequest$, secondRequest$]).subscribe(([res1, res2]) => {
console.log('All done');
if (res1) {
// DO SOMETHING STREAM 1 AFTER ALL STREAMS ARE DONE
}
if (res21) {
// DO SOMETHING STREAM 2 AFTER ALL STREAMS ARE DONE
}
});
Happy coding!