0
votes

I don't know the best way to handle html errors with rxjs in this particular case:

component.ts

private open() {
  this.openSubscription = this.openService
    .open(this.id)
    .subscribe(res => {
      if (res) {
        // do something with result
      } else {
        this.openInError = true;
      }
    });
}

open.service.ts

open(id: number): Observable<OpenContext> {
  const openContextObservable = new Observable<OpenContext>(
  observer => {
  this.openApiService
    .first(id)
    .pipe(
      catchError(err => of(err))
    )
    .subscribe(res => {
      this.openApiService
        .second(res.param1)
        .pipe(
          map(result=> {
            // do something with the result
            observer.next(openContext);
            observer.complete();
          }),
          catchError(err => of(err))
        )
    })
})}

in the service-api i just return this.http.post(...) with some param as Observable

I would like to catch error on first and handle it in the subscribe of the component (subscribe(res => ..., err => ...)). Actually if 'first' is on error, it calls 'second' even if it need the result of 'first' and after that it doesn't return an error, it's just that i handle if there is no response in the subscribe.

What would be the best way to perform that and have a clean code ? i tested with throwError, ... but i'm blocked...

so the code expected in the component would be:

private open() {
  this.openSubscription = this.openService
    .open(this.id)
    .subscribe(
    res => {
      if (res) {
        // do something with result
      }
    },
    err => {
      if (err) {
        this.openInError = true;
      }
    });
}

or something equivalent with .pipe and map.

1

1 Answers

0
votes

1.) Remove catchErrors because this will catch the error and transform the error stream into a non-error stream.

2.) Use switchMap instead of nested subscribes.

open.service.ts

import { switchMap } from 'rxjs/operators';
....
open(id: number): Observable<OpenContext> {
  // you can get rid of openContextObservable as well.
  return this.openApiService
    .first(id)
    .pipe(
      // switch to this observable from the first one
      switchMap(res => this.openApiService.second(res.param1)),
      map(result => {
        // do stuff and transformations here but make sure you return result for your subscriber.
        return result;
      })
    );
)}

component

private open() {
  this.openSubscription = this.openService
    .open(this.id)
    .subscribe(
    res => {
      if (res) {
        // do something with result
      }
    },
    err => {
      if (err) {
        this.openInError = true;
      }
    });
}