2016-08-13 72 views
0

我無法理解如何重構此Angular 2 HTTP包裝器,以便在請求之前從存儲器加載我的頭文件。在Angular 2 HTTP客戶端包裝器中使用承諾

我目前正在加載構造函數中的頭文件,但有時候在請求結束之前從存儲中檢索沒有完成。到目前爲止,我還沒有運氣將標題格式轉換爲承諾,但仍然返回Observable請求對象。取而代之的是Promise被返回,我不得不()去到Observable。

任何指導表示讚賞!

import { Injectable } from '@angular/core'; 
import { Http, Headers, Response, HTTP_PROVIDERS } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 
import { Storage, SqlStorage } from 'ionic-angular'; 


@Injectable() 
export class HttpClient { 
    headers : Headers; 

    constructor(private http: Http) { 

    this.headers = new Headers({ 
     'Accept': 'application/json', 
     'Content-Type': 'application/json; charset=utf-8' 
    }) 

    // Add auth token to headers 
    let storage = new Storage(SqlStorage); 

    storage.get("user").then(
     (u) => { 
     if(u){ 
      let user = JSON.parse(u); 
      this.headers.append('X-User-Email', user.email); 
      this.headers.append('X-User-Token', user.authentication_token); 
     }else{ 
      console.log("User not found in storage.") 
     } 
     } 
    ) 
    } 

    get(url) { 
    console.log("GET headers: ", this.headers) 

    // I want to add a promise here to load the header data 
    // from storage before sending this request. I still 
    // want to return this same Observable http request. 

    return this.http.get(url, { 
     headers: this.headers 
    }) 
    } 
} 

編輯

這裏是我的嘗試,它返回的'Promise<Observable<Response>>'代替Observable

import { Injectable } from '@angular/core'; 
import { Http, Headers, Response, HTTP_PROVIDERS } from '@angular/http'; 
import { Observable } from 'rxjs/Rx'; 
import { Storage, SqlStorage } from 'ionic-angular'; 

/* 
    A custom wrapper to include headers for API authentication. 
    Header info is stored in local storage. 
*/ 

@Injectable() 
export class HttpClient { 

    constructor(private http: Http) { 
    } 

    buildHeaders(){ 
    let headers = new Headers({ 
     'Accept': 'application/json', 
     'Content-Type': 'application/json; charset=utf-8' 
    }) 
    let storage = new Storage(SqlStorage); 

    return storage.get("user").then(
     (u) => { 
     if(u){ 
      let user = JSON.parse(u); 
      headers.append('X-User-Email', user.email); 
      headers.append('X-User-Token', user.authentication_token); 
      return headers; 
     } 
     } 
    ) 
    } 

    get(url) { 
    return this.buildHeaders().then(
     (headers) => { 
     return this.http.get(url, { 
      headers: headers 
     }) 
     } 
    ) 
    } 
} 

這裏是主叫收到錯誤:

this.http.get("http://localhost:3000/confirm_auth_token") 
.subscribe(
    data => console.log(data) 
) 

導致我n:

Error TS2339: Property 'subscribe' does not exist on type 'Promise<Observable<Response>>'. 

如何在HttpClient的get()方法中「展開」承諾?

回答

4

HttpClient.get函數返回一個Promise,所以你需要一個then訪問Observable<Response>Promise解析:

this.http 
    .get("http://localhost:3000/confirm_auth_token") 
    .then((observable) => { 
     observable.subscribe((response) => { console.log(response.text()); }); // or response.json() or whatever 
    }); 

如果你想從你的get函數返回一個Observable,你可以重新排列之類的東西這樣的:

get(url) { 
    return Observable 
     .fromPromise(this.buildHeaders()) 
     .switchMap((headers) => this.http.get(url, { headers: headers })); 
} 

get通話將被這樣的:

this.http 
    .get("http://localhost:3000/confirm_auth_token") 
    .subscribe(response => { console.log(response.text()); }); // or response.json() or whatever 
+0

感謝您的迴應!我希望返回一個Observable,所以它與Angular HTTP對象的功能相同......是可行的嗎? – mikewagz

+0

@cartant一個noob問題,爲什麼你打電話get(url)像這個.http.get(url)而不是像 .get(url)或this.get(url)? http與@ angular/http是否相同?順便說一句,這救了我的生命 –

+0

@SumeetDarade OP稱它是這樣的,因爲它是他的'HttpClient'的一個注入實例 - 所以,不,它跟'@ angular/http'中的'Http'不一樣(他用在他的內部服務)。 – cartant