Search code examples
angulardependency-injectionroutesangular2-services

Angular 2: parent class dependency injected is undefined


I'm trying a implement a service which all other services would extend to handle api responses. I followed this question

Inheritance and dependency injection

and here is my parent class:

import {Injector} from '@angular/core';
import {Router} from "@angular/router";
import {Response} from "@angular/http";

export class ApiService {

  protected _router: Router;

  constructor(injector: Injector) {
    console.log('inside ApiService constructor');
    this._router = injector.get(Router);
    console.log(this._router);
  }

  extractData(res: Response) {
    if (res.json().status === 200) {
      return res.json().data;
    }
  }

  extractResponse(res: Response) {
    if (res.json().status === 200) {
      return res.json();
    }
  }

  handleErrorPromise(error: Response | any) {
    console.log('inside handleErrorPromise');
    console.error(error.message || error);
    console.log(this._router);

    if (error.status === 401 || error.status === "401") {
      // session out
      this._router.navigate(['/login']);
    } else {
      return Promise.reject(error.json().message | error.message || error);
    }
  }

}

and here's the service that extends it:

@Injectable()
export class VitalService extends ApiService {

  constructor(private http: Http, injector: Injector) {
    super(injector);
  }

  getUserVitals(): Promise<VitalDashboardItem[]> {
    return this.http.get('/gch-restful/vital-entry/dashboard')
      .toPromise()
      .then(response => {
        return response.json().data as VitalDashboardItem[];
      })
      .catch(this.handleErrorPromise);
  }

}

but when it reaches the handleErrorPromise in super class

I'm getting this error:

Error: Uncaught (in promise): TypeError: Cannot read property '_router' of undefined
TypeError: Cannot read property '_router' of undefined

I been trying to figure what's wrong for a while now, tried a few things and had no luck. Any help is appreciated

EDIT

changed it like this:

getUserVitals(): Promise<VitalDashboardItem[]> {
    return this.http.get('/gch-restful/vital-entry/dashboard')
      .toPromise()
      .then(response => {
        return response.json().data as VitalDashboardItem[];
      })
      .catch((e) => {
        return this.handleErrorPromise(e)
      });
  }

Solution

  • You're losing the this context here:

    .catch(this.handleErrorPromise);
    

    change it to:

    .catch((e) => { this.handleErrorPromise(e) });
    

    See How to properly do a “bind” in angular2 typescript? for information.