0

I have a backend api to create new product. The frontend angular code needs to call a backend API. How to carry out error handling using ** .subscribe**. I'm using HTTPClient and using Observable and been reading about how RXJS utilizes error handling,

The app should call it as Observable and .subscribe().

the api /create should handle success and failure(error) - If API returns 200: it should print success - If API returns 400, should throw an error

pseudo code

import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

ID = 'foo';
            this.http.post('/api/create', {
                productName: this.form.value.productName,
                productValue: this.form.value.productValue,
            }).subscribe(
                resp => this.onSubmitSuccess(resp), err => this.onSubmitFailure(err)
            );


private onSubmitSuccess(resp) {
        console.log(resp);
        this.ID = resp.ID;
        this.submitSuccess = true;
        this.submitFailed = false;
    }

    private onSubmitFailure(resp) {
        console.log(resp);
        this.submitFailed = true;
        this.submitSuccess = false;
    }  ```

StarJedi
  • 1,410
  • 3
  • 21
  • 34

3 Answers3

0

The earlier versions used to be like:

this.http.get(url).subscribe(
 data =>
 {
   //do something
 },
 error =>
 {
   //handle error
 }
);

With the latest versions, they have deprecated this format. Now you have to do:

this.http.get(url).subscribe(
 {
   next: (data) => 
   {
     //do something
   },
   error: (error) =>
   {
     //handle error
   }
 }
);
Ashique Razak
  • 487
  • 3
  • 8
-1

Handling request errors. It is official Angular documentation

getConfig() {
  return this.http.get<Config>(this.configUrl)
    .pipe(
      catchError(this.handleError)
    );
}

private handleError(error: HttpErrorResponse) {
  if (error.error instanceof ErrorEvent) {
    // A client-side or network error occurred. Handle it accordingly.
    console.error('An error occurred:', error.error.message);
  } else {
    // The backend returned an unsuccessful response code.
    // The response body may contain clues as to what went wrong,
    console.error(
      `Backend returned code ${error.status}, ` +
      `body was: ${error.error}`);
  }
  // return an observable with a user-facing error message
  return throwError(
    'Something bad happened; please try again later.');
};
IAfanasov
  • 4,775
  • 3
  • 27
  • 42
  • This example does not use .subscribe – StarJedi Jun 16 '20 at 19:08
  • sorry, I missed that part. the code inside 'subscribe' function is a smell. `pipes` are way more flexible and should be used unless it's unavoidable. once you get used to RxJs, you totally forget about it (: here is one of the arguments: https://kimsereyblog.blogspot.com/2018/05/async-pipe-versus-subscribe-in-angular.html – IAfanasov Jun 16 '20 at 19:19
-1

If you cannot use async pipe and must use subscribe, using pipe operators is best practice and allows you to unsubscribe when the component is destroyed. It is more functional to use the operators to put logic, as subscribe should be only used to show that that the stream is being observed. It could be something like this:

  ID = 'foo';
  onDestroy = new Subject<boolean>();

  this.http.post('/api/create', {
      productName: this.form.value.productName,
      productValue: this.form.value.productValue,
  }).pipe(
    catchError(err => {
      onSubmitFailure(err);
      return of(err);
    }),
    takeUntil(this.onDestroy),
    tap(resp => onSubitSuccess(resp)),
  ).subscribe();

  onSubmitSuccess(resp) {
      console.log(resp);
      this.ID = resp.ID;
      this.submitSuccess = true;
      this.submitFailed = false;
  }

  onSubmitFailure(resp) {
      console.log(resp);
      this.submitFailed = true;
      this.submitSuccess = false;
  } 

  ngOnDestroy() {
      this.onDestroy$.next(true);
      this.onDestroy$.unsubscribe();
  }