I am creating an extended class of Angular4 Http, so that I can manage the authentication in this top layer service by adding auth header and handling the logout on authentication failure. Here is the service,
import { Injectable } from '@angular/core';
import { Http, XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { AuthService } from '../../auth/auth.service';
@Injectable()
export class HttpService extends Http {
constructor(backend: XHRBackend, options: RequestOptions, private authService: AuthService) {
super(backend, options);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
let token = localStorage.getItem('accessToken');
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}`);
} else {
// we have to add the token to the url object
url.headers.set('Authorization', `Bearer ${token}`);
}
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);
};
}
}
I am using it in my app.module.ts
file as follows.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
// import { HttpModule } from '@angular/http';
import { HttpModule, RequestOptions, XHRBackend } from '@angular/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ReactiveFormsModule } from '@angular/forms';
import { MdMenuModule } from '@angular/material';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
// Services
import { AuthService } from './auth/auth.service';
import { AuthGuard } from './shared/auth-guard.service';
import { SharedModule } from './shared/shared/shared.module';
import { HttpService } from './shared/services/http.service';
export function uFact (backend: XHRBackend, options: RequestOptions) {
return new HttpService(backend, options);
}
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpModule,
AppRoutingModule,
ReactiveFormsModule,
SharedModule,
BrowserAnimationsModule,
MdMenuModule
],
providers: [
AuthService,
AuthGuard,
{
provide: HttpService,
useFactory: uFact,
deps: [XHRBackend, RequestOptions]
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
I have to add AuthService
in the constructor of HttpService
like private authService: AuthService
. But it throws an error in app.module.ts
. I can't instantiate new HttpService(backend, options)
in the exported function uFact
since it needs one more parameter in its constructor. How can I solve this? I am new to Angular.