2016-12-29 82 views
2

我正在嘗試使用繼承來爲我的服務創建一個通用錯誤處理程序,但由於某種原因,當它到達錯誤處理程序本身時,'this'總是顯示爲空,而我無法弄清楚原因。我可以進入錯誤處理得很好,但我總是得到:angular2服務基類繼承 - 爲什麼'this'爲null?

EXCEPTION: Uncaught (in promise): TypeError: Cannot read property 'http' of 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作爲一個函數來捕捉功能。而當它被調用時,它會有不同的這個對象。

您可以將箭頭函數傳遞給catch保留相同的上下文。

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

你必須保持在即使的HandleError被定義爲它仍然表現爲任何其他功能會做一個類的方法頭腦。