Raj Narayanan
Raj Narayanan

Reputation: 3442

"Cannot read property message of null" when reading error status code from http response in Angular 8

I'm developing in Angular 8 and issuing a http post request to a .net core web api and returning a 400 status code if username or password is incorrect. Chrome console says 400 returned but when extracting the status code in the returned observable from the http request response, I get a Cannot read property message of null error message. How can I fix this? Thanks.

Login Component:

this.authService.login(
      {
        username: this.f.username.value,
        password: this.f.password.value
      }
    )
    .subscribe(
        res => {
          if(this.returnUrl != null){
            this.router.navigate([this.returnUrl]);
          }
          else {
            let role = res.role[0];
            this.router.navigate([`${role}`]);
          }

        },
        error => {
            //This line throws the error. the value of error is "cannot read message property of null" and error.status = undefined.
            alert(error.status);
            this.badCredentials = true;
            this.router.navigate(['/login']);
        });

Auth Service:

login(user: {username: string, password: string}) :Observable<any>{
    return this.http.post<any>(`${applicationPaths.loginApiUrl}`, user)
    .pipe(
      tap(response => this.doLoginUser(response)),
      catchError((error): any => {

              return throwError(`Connection Error: ${error}`);
          }
      ));
  }

UPDATE:

I updated my code to the following in my angular application and it still returns the same error message: Server returned code: undefined, error message is: Cannot read property 'message' of null

login(user: {username: string, password: string}) :Observable<any>{
    return this.http.post<any>(`${applicationPaths.loginApiUrl}`, user)
    .pipe(
      tap(response => this.doLoginUser(response)),
      catchError(this.handleError));
  }

  handleError(err: HttpErrorResponse) {
    let errorMessage = '';
    if(err.error instanceof ErrorEvent){

      //a client-side or network error occured. Handle it accordingly.
      errorMessage = `An error occured: ${err.error.message}`;

    } else {
      //The back-end returned an unsuccessful response code.
      errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
    }

    console.error(errorMessage);
    return throwError(errorMessage);
  }

But when I do return BadRequest("incorrect username or password."); or return BadRequest(); it returns the error message Server returned code: undefined, error message is: undefined. So maybe this has to do with the way I'm returning the error code from the web api in the back end. I'm not sure what needs to be fixed there.

Upvotes: 4

Views: 14683

Answers (4)

Campey
Campey

Reputation: 1158

In my case I received this because I'd incorrectly annotated my API method as a HttpGet and not a HttpPost!

The message doesn't really seem to reflect this however when I fixed the API it worked.

Upvotes: 0

Pavel Glos
Pavel Glos

Reputation: 1

  1. In your .NET API: return BadRequest("Incorrect username or password");
  2. In your Angular app:
    catchError((error): any => {
                  return throwError(`Connection Error: ${error.error}`);
              }
          ));

Upvotes: 0

Tony
Tony

Reputation: 20132

Add { observe: 'response' } to your code like this

login(user: {username: string, password: string}) :Observable<any>{
    return this.http.post<any>(`${applicationPaths.loginApiUrl}`, user, { observe: 'response' })
    .pipe(
      tap(response => this.doLoginUser(response)),
      catchError((error): any => {
              return throwError(`Connection Error: ${error}`);
          }
      ));
  }

Then try to access your errror data in your catchError like this

error.statusText
error.statusCode

Edit you should use this code in your controller

 return BadRequest();

Your code

return StatusCode(400);

only return status code

Upvotes: 1

Joey Gough
Joey Gough

Reputation: 3103

status is only provided if you observe: 'response'

try editting your authService like this

login(user: {username: string, password: string}) :Observable<any>{
    return this.http.post<any>(`${applicationPaths.loginApiUrl}`, user
      // NEW CODE HERE
      { observe: 'response' }
    )
    .pipe(
      tap(response => this.doLoginUser(response)),
      catchError((error): any => {

              return throwError(`Connection Error: ${error}`);
          }
      ));
  }

Upvotes: 2

Related Questions