Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle 400 Bad Request From WebApi In Angular 6 (using HttpClient)

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: Screenshot 1

But the same result despite trying multiple code snippet doesn't work out and all it logs 'Bad result' as a response.

Angular Result: Screenshot 2

I did notice though the response lies in the network tab.. just short of an idea to process it.

Error Description: Screenshot 3

What's missing here? your response will be much appreciated !

like image 414
Jason Avatar asked Oct 29 '18 12:10

Jason


People also ask

How do I handle HTTP exceptions in angular?

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.

How can I customize the error message sent by angular httpclient?

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.

How do I customize the error message sent by the httpclient?

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.

Why am I getting a 400 HTTP-status code from my API?

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):


2 Answers

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);
        }
    );
}
like image 166
sanjana tyagi Avatar answered Sep 21 '22 07:09

sanjana tyagi


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.

like image 37
Code Name Jack Avatar answered Sep 21 '22 07:09

Code Name Jack