I need wait for two requests (observables) and do some things. What i need:
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?
catch your errors at the request level and transform them into something usable:
const firstRequest$ = this.doFirstRequest(searchRequest).pipe(
catchError(error => of({error}))
);
const secondRequest$ = this.doSecondRequest(searchRequest).pipe(
catchError(error => of({error}))
);
forkJoin([firstRequest$, secondRequest$]).subscribe(([res1, res2]) => {
if (res1.error && res2.error) {
// both failed
} else if (res1.error || res2.error) {
// one failed
}
if (!res1.error) {
// req 1 success
}
if (!res2.error) {
// req 2 success
}
// whatever you need to do now that they're both done
}, err => {
// can't get here now
});
You need to use forkJoin
for this use case, See ForkJoin docs .
Add catchError
operator to the first stream to handle the first request
Add another catchError
operator to the second stream to handle it
Add tap
operator to the first stream 1
Add 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
}
});
I had a case where one request normally takes much longer than the other, so in the success case I don't want to have to wait for both requests to finish before continuing. As soon as one request finishes, I want to show the received data to the user. But the error handling needed to be different if both requests failed, than if just one failed or when both succeeded.
So I did this:
getRequestASucceeded$ = new ReplaySubject<boolean>(1);
this.getRequestA()
.subscribe( dataA => {
this.getRequestASucceeded$.next(true);
// continue with dataA
},
(err: HttpErrorResponse) => {
this.getRequestASucceeded$.next(false);
}
);
this.getRequestB()
.subscribe( dataB => {
// continue with dataB
this.getRequestASucceeded$.subscribe( hasSucceeded => {
if (hasSucceeded) {
// Both Request succeeded
else {
// RequestA failed, RequestB succeeded
}
},
(err: HttpErrorResponse) => {
this.getRequestASucceeded$.subscribe( hasSucceeded => {
if (hasSucceeded) {
// RequestA succeeded, RequestB failed
else {
// Both Request failed
}
}
);
The Errors are only processed after both requests finished, but the individaul data can get processed right away.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.