Reputation: 41
I want to show a toast that will have text depending upon the status code of the HTTP response. code from service:-
private options = {
headers: new HttpHeaders()
.set("Content-Type", "application/json")
.set("x-app-id", this.appId)
.set("x-app-key", this.appKey)
.set("observe","response")
};
constructor(private http: HttpClient) {}
search(query: string): Observable<{}> {
return this.http.post(this.url, {query: query}, this.options)
}
and this is what I am doing in frontend:-
search() {
this.showcard = false;
this.isLoading = true;
this.nutrix.search(this.searchValue).subscribe((res) => {
if(res){
this.isLoading = false;
this.showcard = true;
this.queryResult = res["foods"][0];
this.imageUrl = this.queryResult['photo']['thumb']
}
console.log(this.queryResult);
},(error) => {
console.log(error);
this.isLoading = false;
});
}
Upvotes: 2
Views: 20556
Reputation: 66
I had the same problem. I found that Arcteezy's solution doesn't work if I'm trying to distinct a 200 from a 201 response, for example. Also, I didn't want to use Interceptors, since my application was too simple. So I went other way.
As you can read on the HttpClient Documentation here, there are optional options where you can ask for the full HttpResponse, instead of only the body. So I did that, and then was able to access the status code from response.status.
Here's a snippet of the code that worked for me:
sendForm(data){
return new Promise((resolve,reject) => {
this.http.post(this.url, data, { observe: 'response' }).subscribe(response => {
if (response.status == 201) {
resolve(response);
} else {
reject(response);
}
},err => {
reject(err);
})
})
}
Bringing it back to the question, I figured what the problem might be.
In the documentation cited before, you can find that "The types of the observe and response options are string unions, rather than plain strings."
this means you can't just pass a regular string, hence the "as const". Also, I noted that you are setting the "observe" option inside the header, which is not the correct place to do so.
The options object should be as follows:
private options = {
observe: 'response' as const,
headers: new HttpHeaders()
.set("Content-Type", "application/json")
.set("x-app-id", this.appId)
.set("x-app-key", this.appKey)
};
This way, you are passing the correct options and is going to receive the entire HttpResponse, even in the success response.
Upvotes: 4
Reputation: 486
It`s better to use Error handling with interceptor
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpResponse,
HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';
import { ToastrService } from "ngx-toastr";
import { Router } from "@angular/router";
export class HttpErrorInterceptor implements HttpInterceptor {
constructor(private toastr: ToastrService, private router: Router) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.pipe(
retry(1),
catchError((error: HttpErrorResponse) => {
if (error instanceof HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.log("Error Event");
} else {
console.log(
`error status : ${error.status} ${JSON.stringify(error.error)}`
);
switch (error.status) {
case 401:
this.router.navigateByUrl("/login");
break;
case 403:
this.router.navigateByUrl("/unauthorized");
break;
case 0:
case 400:
case 405:
case 406:
case 409:
case 500:
this.handleAuthError(error);
break;
}
}
} else {
console.error("something else happened");
}
return throwError(error);
})
)
}
public handleAuthError(error: any) {
console.log("error ", error);
let msg = "";
if (error !== undefined && typeof error === "string") {
msg = error;
} else if (error.error !== undefined && typeof error.error === "string") {
msg = error.error;
} else if (
error.error.error !== undefined &&
typeof error.error.error === "string"
) {
msg = error.error.error;
} else {
msg = error.error.error.errors
? error.error.error.errors[0].errorMessage
: "Something went wrong";
}
this.toastr.error(msg, "", {
timeOut: 3000,
positionClass: "toast-bottom-center",
});
}
}
add this tag in app.module.ts
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HttpErrorInterceptor,
multi: true
}
]
Upvotes: -1
Reputation: 5121
You can just call error.status
from HttpErrorResponse.
this.nutrix.search(this.searchValue).subscribe((res) => {
// response
},(error) => {
console.log(error.status);
});
Upvotes: 0