Reputation: 6001
I need to implement an interceptor for the $http service. I have tried 2 implementations using a factory and a service, they both work OK. this is the implementation in type script:
Service:
export class AuthInterceptorService {
private _authService:Services.IAuthService;
static $inject = ['$q', '$location', '$injector'];
constructor(private $q: ng.IQService, private $location: ng.ILocationService, private $injector: ng.auto.IInjectorService) {
}
private getAuthService = (): Services.IAuthService=> {
if (this._authService == null) {
this._authService = this.$injector.get('authService');
}
return this._authService;
}
public request = (config: ng.IRequestConfig) => {
config.headers = config.headers || {};
var authData = this.getAuthService().authData;
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
}
public responseError = (rejection)=> {
if (rejection.status === 401) {
this.getAuthService().logOut();
}
return this.$q.reject(rejection);
}
}
In app init:
.service('authInterceptorService', Services.AuthInterceptorService)
Factory:
export function AuthInterceptorFactory($q: ng.IQService, $injector: ng.auto.IInjectorService) {
return {
request: (config: ng.IRequestConfig)=> {
config.headers = config.headers || {};
var authData = $injector.get('authService').authData;
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
},
responseError: (rejection)=> {
if (rejection.status === 401) {
$injector.get('authService').logOut();
}
return $q.reject(rejection);
}
};
}
In app init:
.factory('authInterceptorFactory', ['$q', '$injector', Services.AuthInterceptorFactory])
and then on configuration of the interceptor:
.config(['$httpProvider', ($httpProvider:ng.IHttpProvider) => {
$httpProvider.interceptors.push('authInterceptorxxxxx');
}])
As you can see I am using the service location pattern to inject a dependency (using $injector), this is to avoid a circular dependency since the injected service has a dependency on $http.
As I said they both work, I prefer the Service version as it allows me to cache the injection of the dependent service 'authService', in the factory flavour it gets resolved and injected all the time on every request. Is there any problems in using the Service implementation? in Angular docs they refer you should use a factory.
Upvotes: 1
Views: 1229
Reputation: 276353
There is nothing wrong with using a service for an HttpInterceptor. Angular will simply call injector.get
to resolve it, so using a service is fine.
From source $injector.get(interceptorFactory)
https://github.com/angular/angular.js/blob/6f19a6fd33ab72d3908e3418fba47ee8e1598fa6/src/ng/http.js#L207-L210:
forEach(interceptorFactories, function(interceptorFactory) {
reversedInterceptors.unshift(isString(interceptorFactory)
? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));
});
Upvotes: 2