1

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)
      });
  }
Drunken Daddy
  • 7,326
  • 14
  • 70
  • 104

1 Answers1

3

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.

Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • sorry, but it still shows Cannot read property '_router' of undefined – Drunken Daddy Aug 17 '17 at 06:29
  • console.log(this._router); inside handleErrorPromise method – Drunken Daddy Aug 17 '17 at 06:31
  • how did you modify the code? show the updated version – Max Koretskyi Aug 17 '17 at 06:32
  • i put console.log(this); just before console.log(this._router); and it prints undefined – Drunken Daddy Aug 17 '17 at 06:33
  • did you udpate the `.catch((e) => { this.handleErrorPromise(e) });`? if so, put a log here `.catch((e) => { console.log(this._router); this.handleErrorPromise(e) });` – Max Koretskyi Aug 17 '17 at 06:36
  • it is not undefined there, prints the router object – Drunken Daddy Aug 17 '17 at 06:40
  • and you also see `inside handleErrorPromise` but the next statement `console.log(this._router);` logs undefined? – Max Koretskyi Aug 17 '17 at 06:44
  • console.log(this._router); inside handleErrorPromise throws error Uncaught (in promise): TypeError: Cannot read property '_router' of undefined TypeError: Cannot read property '_router' of undefined. I added console.log(this) before before console.log(this._router); in handleErrorPromise. It prints undefined – Drunken Daddy Aug 17 '17 at 06:47
  • well, create a plunker then. If you have `this._router` here `.catch((e) => { console.log(this._router); this.handleErrorPromise(e) });` it should be available inside `this.handleErrorPromise(e)` because `this` references the same object and you're not overwriting it inside the method – Max Koretskyi Aug 17 '17 at 06:50
  • I found that it is when I refresh the page by clicking browser refresh button that console.log(this) prints undefined. Do you any idea why? – Drunken Daddy Aug 17 '17 at 08:12