user2102355
user2102355

Reputation: 41

Angular catch HTTP exception

So i'am trying to show an error message when the user enters an invalid username password combination.

My user.service:

  login(accountCredentials: AccountCredentials): Observable<boolean> {
return this.http.post(UrlHelper.routeTo("auth/login"), JSON.stringify(accountCredentials))
  .map(n => {
    this.authService.setToken(n.json().token);
    this.globalEventsManager.login.emit();
    return true;
  });}

My http.service:

  request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
let token = this.authService.getEncodedToken();
if (typeof url === 'string') { // meaning we have to add the token to the options, not in url
  if (!options) {
    // let's make option object
    options = {headers: new Headers()};
  }
  options.headers.set('Authorization', `Bearer ${token}`);
  options.headers.set('Content-Type', 'application/json;charset=UTF-8');

} else {
  // we have to add the token to the url object
  url.headers.set('Authorization', `Bearer ${token}`);
  url.headers.set('Content-Type', 'application/json;charset=UTF-8');
}
return super.request(url, options).catch(this.catchAuthError(this));}



private catchAuthError(self: HttpService) {
// we have to pass HttpService's own instance here as `self`
return (res: Response) => {
  console.log(res);
  if (res.status === 401 || res.status === 403) {
    // if not authenticated
    console.log(res);
  }
  return Observable.throw(res);
};}

My goal is to return from the login method with a "false" value if the authentication went wrong.

Thank you in advance!

Upvotes: 1

Views: 201

Answers (1)

Tomasz Kula
Tomasz Kula

Reputation: 16837

For rxsj <5.5 you need to use the catch operator. Also side effects should not be handled in the map operator, but in the do operator.

Like this:

login(accountCredentials: AccountCredentials): Observable < boolean > {
  return this.http.post(UrlHelper.routeTo("auth/login"), JSON.stringify(accountCredentials))
    .do(n => {
      this.authService.setToken(n.json().token);
      this.globalEventsManager.login.emit();
    })
    .map(n => {
      return true;
    })
    .catch(e => false);
}

If you are using rxjs > 5.5, the only thing you need to change is rename do to tap, catch to catchError, and wrap everything in the pipe method.

login(accountCredentials: AccountCredentials): Observable < boolean > {
  return this.http.post(UrlHelper.routeTo("auth/login"), JSON.stringify(accountCredentials))
    .pipe(
      tap(n => {
        this.authService.setToken(n.json().token);
        this.globalEventsManager.login.emit();
      }),
      .map(n => {
        return true;
      }),
      catchError(e => false);
    )
}

Upvotes: 1

Related Questions