Below is an Asp.net Core WebAPI which returns bad request with Error details as to its param when let's say duplicate a user is trying to register.
public async Task<IActionResult> Register([FromBody] RegisterModel registerModel)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
//TODO: Use Automapper instead of manual binding
UserName = registerModel.Username,
FirstName = registerModel.FirstName,
LastName = registerModel.LastName,
Email = registerModel.Email
};
var identityResult = await this.userManager.CreateAsync(user, registerModel.Password);
if (identityResult.Succeeded)
{
await signInManager.SignInAsync(user, isPersistent: false);
return Ok(GetToken(user));
}
else
{
Console.WriteLine("Errors are : "+ identityResult.Errors);
return BadRequest(identityResult.Errors);
}
}
return BadRequest(ModelState);
The response is being handled at the Angular side as follows:
user.service.ts
register(user: User) {
// let headers = new Headers({ 'Content-Type': 'application/json' });
//var reqHeader = new HttpHeaders({ 'Content-Type': 'application/json'});
const reqHeader = new HttpHeaders().set('Content-Type', 'application/json')
.set('Accept', 'application/json');
//return this.http.post(this.rootUrl + '/api/account/register', body,{headers : reqHeader});
return this.http.post(this.apiUrl+ '/api/account/register', user,{headers : reqHeader});
}
above method being called out in:
register.component.ts
this.userService.register(this.registerForm.value)
.pipe(map((res: Response) => res.json()))
.subscribe(
data => {
this.alertService.success('Registration successful', true);
this.router.navigate(['/login']);
},
(error:HttpErrorResponse) => {
// let validationErrorDictionary = JSON.parse(error.text());
// for (var fieldName in validationErrorDictionary) {
// if (validationErrorDictionary.hasOwnProperty(fieldName)) {
// this.errors.push(validationErrorDictionary[fieldName]);
// }
// }
// this.alertService.errorMsg(this.errors);
console.log(error.error);
});
When I tried to do Postman I get perfect result as below :
Postman Result:
But the same result despite trying multiple code snippet doesn't work out and all it logs 'Bad result' as a response.
Angular Result:
I did notice though the response lies in the network tab.. just short of an idea to process it.
Error Description:
What's missing here? your response will be much appreciated !
When talking about handling HTTP exceptions in Angular, it is nearly impossible not to talk about RxJs. The Angular framework is heavily bought into the RxJs library—a library that brings reactive programming into the JavaScript ecosystem. Angular's own HttpClient makes use of RxJs under the hood to ensure that the client has an observable API.
Odds are, you don't want to show the user the exact error message that you get from Angular HttpClient when an exception occurs. A great way to customize this message is by throwing your own custom exceptions using throwError.
Odds are, you don't want to show the user the exact error message that you get from Angular HttpClient when an exception occurs. A great way to customize this message is by throwing your own custom exceptions using throwError. First, update your BooksService to throw a custom error depending on the final status of the HTTP request.
You are getting 400 Http-status code from your API in angular app AND in postman as well: BTW: 400 status is API expected behavior. It failed to create user and sends error description along with appropriate HTTP-status (400).If you want to handle this API error, the best choice would be something like (referred angular HttpErrorResponse type):
I was also facing the same problem in angular 7. However I fixed this today using below code :
In service :
registerUser(userdata): Observable<any> {
return this.httpClient.post('url', userdata).pipe(catchError(this.handleError));
}
handleError(error: HttpErrorResponse) {
return throwError(error);
}
In register.component.ts :
postData() {
this.auth.registerUser(userdata).subscribe(
(resp) => {
console.log(resp);
},
(error) => {
console.log(error.error);
}
);
}
Dotnet Core 400 Identity error response is an array of {code,description}. So to handle it in typescript, first define an interface(not required actually,but for strict type checking.
interface ClientError {
code: string;
description: string;
}
Then in the part where you handle error, do following,
(error:HttpErrorResponse) => {
if(error.status===400){
const errors: Array<ClientError> = error.error;
errors.forEach(clientError => {
console.log(clientError.code);
});
}
}
Update: This is specific to Identity Framework. (Login and Registration). In other areas, Error Handling will need a manual work to align with this pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With