2016-02-11 75 views
5

我正在寫一個小工具功能換到AngularJS http.get調用必要的認證頭:RxJS和AngularJS HTTP - 我該如何實現?

get(endpoint: string): Observable { 
    var headers = new Headers(); 
    this._appendAuthentificationHeaders(headers, this.user.credentials); 

    return this.http.get(endpoint, { headers: headers }) 
      .map(res => res.json()); 
} 

這裏的關鍵是,如果this.user爲null,該方法將剛崩潰。 所以我有三種選擇:

  1. 返回null,檢查每一個調用的返回值...
  2. 拋出一個異常
  3. 找到一種方法,也返回RxJS可觀察對象,將直接觸發錯誤處理器。

我想實現第三種方法,因爲它可以讓我統一這個方法的行爲:無論發生什麼事,它總是返回一個可觀察對象。

  • 你有關於如何做到這一點的想法?
  • 我是否必須創建一個新的Observable並將它們合併?
  • 我該怎麼辦?

回答

3

如果usernull,你可以簡單地返回原始觀察到觸發一個錯誤:

if (this.user == null) { 
    return Observable.create((observer) => { 
    observer.error('User is null'); 
    }); 
} 

(...) 

或充分利用throw操作:

if (this.user == null) { 
    return Observable.throw('User is null'); 
} 

(...) 

這樣的第二種方法將調用subscribe方法:

observable.subscribe(
    (data) => { 
    (...) 
    }, 
    (err) => { 
    // Will be called in this case 
    } 
); 
+0

我將爲Observable.throw('User is null'); 非常感謝! – Clement

+1

手冊'Observable.throw()'已被證明是我在Rx/angular 4中遇到的使用最少,最有用的錯誤處理模式之一。 – msanford

0

我認爲最簡潔的方法是將整個函數體包裝爲可觀察對象,因爲它會將任何意外錯誤轉變爲可觀察錯誤。事情是這樣的:

get(endpoint: string): Observable { 
    return Rx.Observable.defer(() => { 
    var headers = new Headers(); 
    this._appendAuthentificationHeaders(headers, this.user.credentials); 
    return Rx.Observable.just(headers); 
    }) 
    .flatMap(headers => this.http.get(endpoint, { headers: headers })) 
    .map(res => res.json()); 
} 

不過我還是不同意http.get返回,而不是一個承諾可觀察到的。由於這些是單值的可觀測值,因此您的函數可能是一個簡單的異步函數(sry,js而不是ts):

async get(endpoint) { 
    var headers = new Headers(); 
    this._appendAuthentificationHeaders(headers, this.user.credentials); 
    const res = await this.http.get(endpoint, { headers })).toPromise(); 
    return res.json(); 
} 
+0

感謝您的回答! 在我看來,Observable是promise的超集,所以讓我們只使用一個一致的api。 – Clement

+0

@Clement使Promise和Observables有所不同的最大區別是Observable是可重放的。當你試圖用observables實現一些緩存機制時,記住這一點:)但是,可觀察性是promise的超集。我想我們將不得不適應異步等待觀察。 –

+0

你可以重玩的是什麼意思? – Clement