Home > Blockchain >  RxJS/Angular 11 wait for 2 observables complete and errors handling
RxJS/Angular 11 wait for 2 observables complete and errors handling

Time:11-10

I need wait for two requests (observables) and do some things. What i need:

  1. Wait for requests (observables) end
  2. If one of them failed - display one error
  3. If both of them failed - display second error
  4. If first success - do some things
  5. 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:

  1. You need to use forkJoin for this use case, See ForkJoin docs.

  2. Add catchError operator to the first stream to handle the first request

  3. Add another catchError operator to the second stream to handle it

  4. Add tap operator to the first stream 1

  5. 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
  }
});

Happy coding!

  • Related