valik
valik

Reputation: 2094

How do i catch status code with httpClient angular

I am working with http client i have a in my service

  private extractData(response: HttpResponse<Truck>) {
    const body = response;
    return body || {};
  } 

  private handleError(err: HttpErrorResponse) {
    let errorMessage: string;

    // A client-side or network error occurred.
    if (err.error instanceof Error) {
      errorMessage = `An error occurred: ${err.error.message}`;
    }
  ,
    else {
      errorMessage = `server side  ${err.status}, body was: ${err.error}`;
    }

    console.error(errorMessage || err);
    return Observable.throw(err.status);
  }

and a create method post

createTruck(truck: Truck): Observable<number> {
     return this.http.post(this.baseUrl, JSON.stringify(truck), {headers: this.headers})
      .pipe(
        map(this.extractData),
        tap(data => console.log(JSON.stringify(data))),
        catchError(this.handleError));
  }

In my component im trying to get the status code ,the method succesfully posts but i have errors when i try a duplicate truckCode which i want to be returned as a message in the app.

processForm() {

    this.processValidation = true;
    if (this.truckForm.invalid) {
      return; //Validation failed, exit from method.
    }

    // if we are here then all good
     this.preProcessConfigurations()

    let truckCode = this.truckForm.get('truckCode').value.trim();
    let date = this.truckForm.get('date').value.trim();
    let description = this.truckForm.get('description').value.trim();


    if (this.truck.truckId == undefined) {
      let truck= new Truck(null, truckCode, date, description);

      this.truckService.createTruck(truck).subscribe((truck) => {
        console.log(truck);
        this.router.navigate(['/trucks'])
      },
        errorCode => this.statusCode = errorCode);

    }else {
      let truck= new Truck(this.truck.truckId, truckCode, date, description);

      this.truckService.updateTrucks(truck).subscribe((truck) => {
        console.log(truck);
        this.router.navigate(['/trucks'])
      }, errorCode => this.statusCode = errorCode);

    }
  }

so in my html i did this to get the status code but it doesnt work, i i think there is a problem with the service as it maps the body and not a status code what can i do ? here is my html part of it

           <!--form end-->
            </form>
            <br/>
            <div *ngIf="statusCode; else processing">

              <div *ngIf="statusCode === 201" [ngClass] = "'success'">
                Article added successfully.
              </div>
              <div *ngIf="statusCode === 409" [ngClass] = "'success'">
                Article already exists.
              </div>
              <div *ngIf="statusCode === 400" [ngClass] = "'success'">
                Article already exists.
              </div>
              <div *ngIf="statusCode === 200" [ngClass] = "'success'">
                Article updated successfully.
              </div>
              <div *ngIf="statusCode === 204" [ngClass] = "'success'">
                Article deleted successfully.
              </div>
              <div *ngIf="statusCode === 500" [ngClass] = "'error'">
                Internal Server Error.
              </div>
            </div>

            <ng-template #processing>
              <img *ngIf="requestProcessing" src="assets/images/loading.gif">
            </ng-template>
          </div>

the #processing part works but status code doesnt any help please thank you.

How it looks now , after i added it gave error status does not exist on type truck, what could it b

e

  this.truckService.createTruck(truck).subscribe((truck) => {
    console.log(truck['_body']);
    this.router.navigate(['/trucks'])
  }, this.statusCode = truck.status;
    // (errorCode: Response) => { this.statusCode = errorCode.status})
    // errorCode => this.statusCode = errorCode); 
  this.truckService.updateTrucks(truck).subscribe((truck) => {
    console.log(truck['_body']);
    this.router.navigate(['/trucks'])
  },this.statusCode = truck.status;
    // (errorCode: Response) => { this.statusCode = errorCode.status});

Upvotes: 1

Views: 3119

Answers (3)

valik
valik

Reputation: 2094

So everything was ok except that this is angular 4 and in the static method throw doesnt come with the import of rxjs/Observable, this was the problem

private handleError(error: HttpErrorResponse| any) {
    let errorMessage: string;

    // A client-side or network error occurred.
    if (error.error instanceof Error) {
      errorMessage = `An error occurred: ${error.error.message}`;

    } else {
      errorMessage = `server side  ${error.status}, body was: ${error.error}`;
    }

    console.error(error.ok || error);
    return Observable.throw(error.status);// observable throw is not a function 
  }

you to explicitly do import

 import 'rxjs/add/observable/throw'; 

with this it will now work

Upvotes: 1

spaceman
spaceman

Reputation: 649

I did that by simply:

In your truckService:

import { map, tap, catchError } from 'rxjs/operators';
import { of } from 'rxjs/observable/of';

...

        createTruck(truck: Truck): Observable<number> {
         return this.http.post(this.baseUrl, JSON.stringify(truck), {headers: this.headers})
          .pipe(
            map(this.extractData),
            tap(data => console.log(JSON.stringify(data))),
            catchError(this.handleError));
      }

In your component:

processForm() {

  this.processValidation = true;
  if (this.truckForm.invalid) {
    return; //Validation failed, exit from method.
  }

  // if we are here then all good
   this.preProcessConfigurations()

  let truckCode = this.truckForm.get('truckCode').value.trim();
  let date = this.truckForm.get('date').value.trim();
  let description = this.truckForm.get('description').value.trim();


  if (this.truck.truckId == undefined) {
    let truck= new Truck(null, truckCode, date, description);

    this.truckService.createTruck(truck).subscribe((truck) => {

      this.router.navigate(['/trucks']);
    },
    error => {
      if(error){
        this.statusCode=error;
        console.log('error code'+ this.statusCode)
      }
    });

  }else {
    let truck= new Truck(this.truck.truckId, truckCode, date, description);

    this.truckService.updateTrucks(truck).subscribe((truck) => {

      this.router.navigate(['/trucks']);
    },
    error => {

        if(error){
          this.statusCode=error;
          console.log('error code'+ this.statusCode)
        }

    });

  }
}

Edit: Better approach that works. Get that in your subscribe and assign it to the variable you want. Leaving error just for logging, that way you can use data you retrieve. error is used for errorHandling, not passing data. That you will do on .subscribe.

You can see that this way you are receiving a full Response with everything you need, like headers, ok, status, statusText, type, url and _body.

Hope it helps

Upvotes: 1

user6749601
user6749601

Reputation:

You have to cast the error first to Response-object. Then you can access the error code.

import { Response } from '@angular/http';

if (this.truck.truckId == undefined) {
  let truck= new Truck(null, truckCode, date, description);

  this.truckService.createTruck(truck).subscribe((truck) => {
    console.log(truck);
    this.router.navigate(['/trucks'])
  },
    (errorCode: Response) => { this.statusCode = errorCode.status });

}else {
  let truck= new Truck(this.truck.truckId, truckCode, date, description);

  this.truckService.updateTrucks(truck).subscribe((truck) => {
    console.log(truck);
    this.router.navigate(['/trucks'])
  }, 
     (errorCode: Response) => { this.statusCode = errorCode.status });

}

This should do.

Upvotes: 1

Related Questions