2016-12-29 4 views
2

私のサービスの汎用エラーハンドラを作成するために継承を使用しようとしていますが、何らかの理由でエラーハンドラ自体に到達すると 'this'は常にnullと思われます。私はうまくエラーハンドラに入ることができますが、私は常に取得:angular2サービスベースクラスの継承 - 'this'はなぜnullですか?

EXCEPTION: Uncaught (in promise): TypeError: Cannot read property 'http' of null

私が間違っている/行方不明です何任意のアイデアを?どのように 'これ'がnullになることができるか分からない?ここで

は、サービスのための私の全体の基底クラスである:

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 

@Injectable() 
export class HttpServiceBase { 

    constructor(public http: Http) { 
     console.log('http', this.http); //just do this to prove that it is there - it is! 
    } 

    handleError(error: any): Promise<any> { 
     console.error('Application Error', error); //this logs fine 

     // TypeError: Cannot read property 'http' of null 
     this.http.get('/Account/IsLoggedIn') 
      .map(response => console.log('RESPONSE: ', response)); 

     return Promise.reject(error.message || error); 
    } 
} 

そして、これは私の継承クラスである:

import 'rxjs/add/operator/toPromise'; 
import { Injectable } from '@angular/core'; 
import { Headers, Http } from '@angular/http'; 
import { HttpServiceBase } from './http-service.base'; 
import { Hero } from './hero'; 

@Injectable() 
export class HeroService extends HttpServiceBase { 

    private headers = new Headers({ 'Content-Type': 'application/json' }); 
    private heroesUrl = 'http://localhost:57569/Home/Heroes'; 

    constructor(http: Http) { super(http); } 

    getHeroes(): Promise<Hero[]> { 
     console.log('getting heroes'); 

     return this.http.get(this.heroesUrl + '-force-error') //so it will error out 
      .toPromise() 
      .then(response => response.json() as Hero[]) 
      .catch(this.handleError); 
    } 
} 

答えて

3

コールバックとして使用されることになっているメソッドについては、それらを構築時のコンテキストにバインドすることをお勧めします。活字体では、このクラスのフィールドと矢印の方法を経由して達成可能である:

constructor(public http: Http) {} 

handleError = (error: any): Promise<any> { ... } 

メソッド呼び出しに結合とは対照的に、これは間違った文脈の可能性を排除します。

より好ましい方法は次のようになります。

constructor(public http: Http) { 
    this.handleError = this.handleError.bind(this); 
} 

handleError(error: any): Promise<any> { ... } 

それは同じことを行いますが、それは/モックHttpServiceBase.prototype.handleError前にクラスのインスタンスをスパイすることができますので、より良いテスト容易性を持っています。

+0

正解ですが、これが最も完成しました。どうもありがとうございました! – naspinski

+0

もちろん、よろしくお願いします。 – estus

2

これはそれを修正する任意のチャンス?

.catch(this.handleError.bind(this)); 
4

あなたがキャッチ関数への関数としてhandleErrorのを渡しているので、それは起こります。それが呼び出されると、別のこのオブジェクトがあります。

矢印機能をに渡すと、は同じコンテキストを保持できます。 handleErrorのが他の関数が行うように、それはまだ動作しますクラスのメソッドとして定義されている場合でも、あなたが心に留めておく必要はあり

.catch(error => this.handleError(error)); 

関連する問題