2

angular2-jwt provides an AuthHttp wrapper for the native Angular http class that automatically includes the http authorization header with each request. In my services I am usually calling a backend api like this

  getThings(): Observable<Thing[]> {
    return this.http.get(environment.apiEndpoint + '/things')
                    .map(res => res.json().data)
                    .catch(res => this.handleError(res));
  }

with an error handler like

private handleError(error: Response | any) {
  let errMsg: string;
  if (error instanceof Response) {
    const body = error.json() || '';
    const err = body.error || JSON.stringify(body);
    errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
  } else {
    errMsg = error.message ? error.message : error.toString();
  }
  // If JWT is expired open a new window to log in again
  if (errMsg.indexOf('No JWT present or has expired') !== -1) {
    window.open(environment.apiEndpoint + '/loginToApp?expired', '_blank', 'height=570,width=520');
  }
  console.error(error);
  return Observable.throw(errMsg);
}

I keep repeating the handleError method in all my services and I would like to know if there is a way to make this DRY. Is there a way to define a generic error handler for all http requests?

I'd like to avoid having to call catch each time if possible. Is there a way to extend the http class to automatically catch errors on each request and then in special situations I can add custom catch logic on a case by case basis?

I could export the method from another file and import it in each of my services but I think there has got to be a better way. Thanks for any suggestions.

UPDATE: I ended up extending the AuthHttp class from angular2-jwt.

import { Http, RequestOptions, Response, Request, RequestOptionsArgs } from '@angular/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

import { AuthHttp, AuthConfig } from 'angular2-jwt';

export class ApiHttp extends AuthHttp { 

  public request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    return super.request(url, options).catch(res => this.handleError(res));
  }

  private handleError(error: Response | any) {
    // error handling then rethrow the error
    return Observable.throw(error);
  }
}

1 Answer 1

3

You can create custom service CustomAuthHttp like AuthHTTP Wrapper. Like wrapper adds header, in CustomAuthHttp you can catch error. Then in your code inject CustomAuthHttp instead of AuthHTTP and use.

@Injectable()
export class CustomAuthHttp {

  constructor(private http: AuthHttpWrapper) { }

  get(url: string) {
    return this.http.get(url)
      .catch(res => this.handleError(res));
  }

  private handleError(error: Response | any) {
    // your code
    return Observable.throw('');
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I ended up creating a new class extending the AuthHttp class from angular2-jwt. I then overrode the AuthHttp's request method and attached my error handling method

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.