Reputation: 2568
I have a service call that when it returns a 404 error, I want to display the message that comes from the server when the status is 404. So, in event of an error or success, I get a post json that gives me a status code and message that indicates if it was successful or not.
Currrently, I have this service call:
this._transactionService.findExistingTransaction(user, searchNumber)
.subscribe(data => {
this.transactionResponse = data;
console.log(JSON.stringify(this.transactionResponse));
this.router.navigate(['/edit-transaction-portal'], {queryParams: {bill: searchNumber}});
this.onDismiss();
}, (err) => { this.displayErrors = true;});
on error, it will set the bool displayErrors = true and then I can show the error message in my UI.
In html code:
<input #inputtedNumber class="transactionInput" placeholder="{{numberPlaceholder | translate }}"/>
<div class="error-msg1" *ngIf="displayErrors" style="margin-left:90px;" name="errorMsg">
{{transactionResponse._errorDetails._message}} </div>
This is the json that gets posted back when I directly try to access api endpoint:
{
"_transactionNumber":null,
"_order":null,
"_errorDetails":{
"_status":"404",
"_message":"Number is not available"
}
}
I bind to the transactionResponse object that I get back from my service call. Unfortunately, although I believe this should work, I get the issue that _errorDetails is undefined and so nothing shows up.
I wonder if this is the right setup for something like this? If now, how can I fix it?
Thanks!
EDIT: Duplicate SO post with no answer: How to read Custom error message from backend in Angular 4/2
Upvotes: 7
Views: 12528
Reputation: 3711
I think you can use a typed response:
On your error
notification type you could have something like:
err => {
this.localErrorResponse = err as ErrorResponse;
this._order= this.localErrorResponse._order;
}
inside your class, also, you could have:
import { ErrorResponse } from './error-response';
localErrorResponse: ErrorResponse;
_order: string;
and then, you could have your ErrorResponse
class like:
import { ErrorDetail } from './error-detail';
export class ErrorResponse{
_transactionNumber: number;
_order: string;
_errorDetails: ErrorDetail;
}
and class ErrorDetail
export class ErrorDetail {
_status: number;
_message: string
}
then you can map some other variables, as _order
(this._order
), or get them from your localErrorResponse
(this.localErrorResponse
) variable
Upvotes: 2
Reputation: 4798
I have a service call that when it returns a 404 error, I want to display the message that comes from the server when the status is 404
...
I bind to the transactionResponse object that I get back from my service call. Unfortunately, although I believe this should work, I get the issue that _errorDetails is undefined and so nothing shows up.
Try this:
Upvotes: 0
Reputation: 461
The response body from the server should be in the error
property of the error response that comes back in the error
callback.
Regarding HttpErrorResponse, the documentation states:
Observable
response stream will be wrapped in an HttpErrorResponse
to provide additional context about the state of the HTTP layer when the error occurred. The error property will contain either a wrapped Error
object or the error response returned from the server.If you want to use the same transactionResponse
to display the errors, then assign the error
property of the err
that comes back to this.transactionResponse
.
Service Call
this._transactionService.findExistingTransaction(user, searchNumber).subscribe(
(data) => {
this.transactionResponse = data;
console.log(JSON.stringify(this.transactionResponse));
this.router.navigate(['/edit-transaction-portal'], {queryParams: {bill: searchNumber}});
this.onDismiss();
},
(err: HttpErrorResponse) => {
this.displayErrors = true;
// assign the error property of the err that comes back to the transactionResponse
this.transactionResponse = err.error;
});
HTML Then this will work.
<input #inputtedNumber class="transactionInput" placeholder="{{ numberPlaceholder | translate }}"/>
<div class="error-msg1" *ngIf="displayErrors" style="margin-left:90px;" name="errorMsg">
{{transactionResponse._errorDetails._message}}
</div>
There was some work done to this part of Angular in September 2017. parse error response body for responseType "json" So you may need to update Angular depending on your version.
This solution was tested on the following:
Edit: StackBlitz example
HttpErrorResponse StackBlitz example
This example makes some assumptions about what the service looks like and what endpoint it is calling. The service makes a POST
call to www.google.com
. This fails and returns an HttpErrorResponse
.
{
"isTrusted": true
}
The error
property of the HttpErrorResponse
is assigned to this._transactionResponse
. This can then be accessed in the template and displayed in the browser.
Upvotes: 7
Reputation: 18123
Your problem is that in the event of an error, your
data => {
this.transactionResponse = data;
code does not get called - you got an error response, not a normal response afterall.
Try to get the information from the
}, (err) => { this.transactionResponse = err
part.
Upvotes: 2