Getting started with Angular 2Dynamically add components using ViewContainerRef.createComponentPipesRouting (3.0.0+)Http InterceptorDirectivesInstalling 3rd party plugins with [email protected]Testing an Angular 2 AppRoutingOptimizing rendering using ChangeDetectionStrategyLifecycle HooksDirectives & components : @Input @OutputAngular RXJS Subjects and Observables with API requestsZone.jsServices and Dependency InjectionAngular 2 Forms UpdateDetecting resize eventsBootstrap Empty module in angular 2Advanced Component ExamplesBypassing Sanitizing for trusted valuesAngular2 Custom ValidationsAngular 2 Data Driven FormsAngular - ForLoopFeature ModulesAngular2 In Memory Web APIAhead-of-time (AOT) compilation with Angular 2Debugging Angular2 typescript application using Visual Studio CodeCRUD in Angular2 with Restful APIComponent interactionsUse native webcomponents in Angular 2Lazy loading a moduleUpdate typingsMocking @ngrx/StoreHow to use ngforngrxAnimationCommonly built-in directives and servicesHow to Use ngifTesting ngModelCreate an Angular 2+ NPM packageAngular2 CanActivateAngular 2 - ProtractorExample for routes such as /route/subroute for static urlsAngular2 Input() output()Page titleunit testingAngular-cliOrderBy PipeAngular2 AnimationsAngular 2 Change detection and manual triggeringAngular2 DatabindingBrute Force UpgradingEventEmitter ServiceAngular2 provide external data to App before bootstrapUsing third party libraries like jQuery in Angular 2Component interactionsAttribute directives to affect the value of properties on the host node by using the @HostBinding decorator.TemplatesConfiguring ASP.net Core application to work with Angular 2 and TypeScriptAngular2 using webpackAngular material designDropzone in Angular2custom ngx-bootstrap datepicker + inputangular reduxCreating an Angular npm libraryBarrelangular-cli test coverageService WorkerComponentsModules

Http Interceptor

Other topics

Remarks:

What we do with HttpServiceLayer class is extend the Http class from angular and add our own logic to it.

We then inject that class in the bootstrap class of the application and tell angular that were we import the Http class, in the back to insert the HttpServiceLayer.

Anywhere in the code we can simply import

import { Http } from '@angular/http';

But our class will be used for each call.

Simple Class Extending angular's Http class

import { Http, Request, RequestOptionsArgs, Response, RequestOptions, ConnectionBackend, Headers } from '@angular/http';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/empty';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import { ApplicationConfiguration } from '../application-configuration/application-configuration';

/**
* This class extends the Http class from angular and adds automaticaly the server URL(if in development mode) and 2 headers by default:
* Headers added: 'Content-Type' and 'X-AUTH-TOKEN'.
* 'Content-Type' can be set in any othe service, and if set, it will NOT be overwritten in this class any more.
*/
export class HttpServiceLayer extends Http {

  constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private _router: Router, private appConfig: ApplicationConfiguration) {
    super(backend, defaultOptions);
  }

  request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    this.getRequestOptionArgs(options);
    return this.intercept(super.request(this.appConfig.getServerAdress() + url, options));
  }

  /**
  * This method checks if there are any headers added and if not created the headers map and ads 'Content-Type' and 'X-AUTH-TOKEN'
  * 'Content-Type' is not overwritten if it is allready available in the headers map
  */
  getRequestOptionArgs(options?: RequestOptionsArgs): RequestOptionsArgs {
    if (options == null) {
      options = new RequestOptions();
    }
    if (options.headers == null) {
      options.headers = new Headers();
    }

    if (!options.headers.get('Content-Type')) {
      options.headers.append('Content-Type', 'application/json');
    }

    if (this.appConfig.getAuthToken() != null) {
      options.headers.append('X-AUTH-TOKEN', this.appConfig.getAuthToken());
    }

    return options;
  }

  /**
  * This method as the name sugests intercepts the request and checks if there are any errors.
  * If an error is present it will be checked what error there is and if it is a general one then it will be handled here, otherwise, will be
  * thrown up in the service layers
  */
  intercept(observable: Observable<Response>): Observable<Response> {

    //  return observable;
    return observable.catch((err, source) => {
      if (err.status == 401) {
        this._router.navigate(['/login']);
        //return observable;
        return Observable.empty();
      } else {
        //return observable;
        return Observable.throw(err);
      }
    });
  }
}

Using our class instead of Angular's Http

After extending the Http class, we need to tell angular to use this class instead of Http class.

In order to do this, in our main module(or depending on the needs, just a particular module), we need to write in the providers section:

export function httpServiceFactory(xhrBackend: XHRBackend, requestOptions: RequestOptions, router: Router, appConfig: ApplicationConfiguration) {
  return  new HttpServiceLayer(xhrBackend, requestOptions, router, appConfig);
}

import { HttpModule, Http, Request, RequestOptionsArgs, Response, XHRBackend, RequestOptions, ConnectionBackend, Headers } from '@angular/http';
import { Router } from '@angular/router';

@NgModule({
  declarations: [ ... ],
  imports: [ ... ],
  exports: [ ... ],
  providers: [
    ApplicationConfiguration,
    {
      provide: Http,
      useFactory: httpServiceFactory,
      deps: [XHRBackend, RequestOptions, Router, ApplicationConfiguration]
} 
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Note: ApplicationConfiguration is just a service I use to hold some values for the duration of the application

Simple HttpClient AuthToken Interceptor (Angular 4.3+)

import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { UserService } from '../services/user.service';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AuthHeaderInterceptor implements HttpInterceptor {

  constructor(private userService: UserService) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (this.userService.isAuthenticated()) {
      req = req.clone({
        setHeaders: {
          Authorization:  `Bearer ${this.userService.token}`
        }
      });
    }
    return next.handle(req);
  }
}

Providing Interceptor (some-module.module.ts)

{provide: HTTP_INTERCEPTORS, useClass: AuthHeaderInterceptor, multi: true},

Contributors

Topic Id: 1413

Example Ids: 4620,4621,32691

This site is not affiliated with any of the contributors.