0

I am using angular 2 and I want to intercept all responses and redirect user to login page if session is expired.

I came across This Question, and I have been following This Answer.

Everything compiles correctly. By inspecting in debugger I can see that constructor has been called, but super.request has never been reached.

Here is my extended HTTP Module

import { Injectable } from '@angular/core';
import { Request, XHRBackend, RequestOptions, Response, Http, RequestOptionsArgs, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class AuthenticatedHttpService extends Http {

  constructor(backend:XHRBackend, defaultOptions:RequestOptions) {
    super(backend, defaultOptions);
  }

  request(url:string | Request, options?:RequestOptionsArgs):Observable<Response> {
    return super.request(url, options).catch((error:Response) => {
      if ((error.status === 401 || error.status === 403) && (window.location.href.match(/\?/g) || []).length < 2) {
        console.log('The authentication session expires or the user is not authorised. Force refresh of the current page.');
      }
      return Observable.throw(error);
    });
  }
}

In app.module.ts I have provider defined as

...
providers: [{
    provide: HttpModule,
    useClass: AuthenticatedHttpService
  }, SessionService, MyService]
...

And in MyService I have

import {Injectable} from "@angular/core";
import {Http, Response, Headers, RequestOptions} from "@angular/http";
import {Observable} from "rxjs/Rx";
import { environment } from '../../../environments/environment';

@Injectable()
export class MyService {
  apiUrl:string = environment.apiUrl;
  constructor(private http:Http) {
  }

  getData() {
    let headers = new Headers();
    headers.append('x-access-token', 'my-token');
    return this.http
      .get(this.apiUrl + '/getData', {headers: headers}
      ).map((res:Response) => res.json());
  }
}

Can anyone point me in a right direction what am I doing wrong?

Kukic Vladimir
  • 1,010
  • 4
  • 15
  • 22

2 Answers2

0
  1. Use a base service
  2. Inherit all your services from this base service
  3. Write all your global code inside this base service

This would be the best solution

Ali Adravi
  • 21,707
  • 9
  • 87
  • 85
0

After further inspection I have found a solution for my specific problem.

First I had to apply changes to app.module.ts regarding Http Provider like this

{
  provide: AuthenticatedHttpService,
    useFactory: (backend: XHRBackend, options: RequestOptions) => {
      return new AuthenticatedHttpService(backend, options);
    },
      deps: [XHRBackend, RequestOptions]
}, 

Then in MyService I am using AuthenticatedHttpService instead Http like this.

import {Injectable} from "@angular/core";
import {AuthenticatedHttpService} from '../../_services/authenticated-http.service';
import {Observable} from "rxjs/Rx";
import { environment } from '../../../environments/environment';

@Injectable()
export class MyService {
  apiUrl:string = environment.apiUrl;
  constructor(private http:AuthenticatedHttpService) {
  }

  getData() {
    let headers = new Headers();
    headers.append('x-access-token', 'my-token');
    return this.http
      .get(this.apiUrl + '/getData', {headers: headers}
      ).map((res:Response) => res.json());
  }
}

After I have applied these changes everything started working as expected.

Kukic Vladimir
  • 1,010
  • 4
  • 15
  • 22