2016-02-08 46 views
60

我目前正在試圖在AngularJS 1. *過去4年中與Angular2和TypeScript合作後自學自學!我不得不承認我很討厭它,但是我確信我的靈感時刻即將到來......無論如何,我已經在我的虛擬應用程序中編寫了一項服務,可以從我編寫的服務於JSON的虛假後端獲取http數據。用TypeScript中的Angular2中的http數據鏈接RxJS Observable

import {Injectable} from 'angular2/core'; 
import {Http, Headers, Response} from 'angular2/http'; 
import {Observable} from 'rxjs'; 

@Injectable() 
export class UserData { 

    constructor(public http: Http) { 
    } 

    getUserStatus(): any { 
     var headers = new Headers(); 
     headers.append('Content-Type', 'application/json'); 
     return this.http.get('/restservice/userstatus', {headers: headers}) 
      .map((data: any) => data.json()) 
      .catch(this.handleError); 
    } 

    getUserInfo(): any { 
     var headers = new Headers(); 
     headers.append('Content-Type', 'application/json'); 
     return this.http.get('/restservice/profile/info', {headers: headers}) 
      .map((data: any) => data.json()) 
      .catch(this.handleError); 
    } 

    getUserPhotos(myId): any { 
     var headers = new Headers(); 
     headers.append('Content-Type', 'application/json'); 
     return this.http.get(`restservice/profile/pictures/overview/${ myId }`, {headers: headers}) 
      .map((data: any) => data.json()) 
      .catch(this.handleError); 
    } 

    private handleError(error: Response) { 
     // just logging to the console for now... 
     console.error(error); 
     return Observable.throw(error.json().error || 'Server error'); 
    } 
} 

現在在組件我想運行(或鏈)都getUserInfo()getUserPhotos(myId)方法。在AngularJS這很容易,因爲在我的控制,我會做這樣的事情,以避免「厄運的金字塔」 ......

// Good old AngularJS 1.* 
UserData.getUserInfo().then(function(resp) { 
    return UserData.getUserPhotos(resp.UserId); 
}).then(function (resp) { 
    // do more stuff... 
}); 

現在,我已經嘗試在做我的組件類似的東西(更換.then.subscribe)然而,我的錯誤控制檯瘋了!

@Component({ 
    selector: 'profile', 
    template: require('app/components/profile/profile.html'), 
    providers: [], 
    directives: [], 
    pipes: [] 
}) 
export class Profile implements OnInit { 

    userPhotos: any; 
    userInfo: any; 

    // UserData is my service 
    constructor(private userData: UserData) { 
    } 

    ngOnInit() { 

     // I need to pass my own ID here... 
     this.userData.getUserPhotos('123456') // ToDo: Get this from parent or UserData Service 
      .subscribe(
      (data) => { 
       this.userPhotos = data; 
      } 
     ).getUserInfo().subscribe(
      (data) => { 
       this.userInfo = data; 
      }); 
    } 

} 

我很明顯做錯了什麼...我最好怎麼用Observables和RxJS?對不起,如果我問愚蠢的問題...但感謝提前的幫助!聲明我的HTTP頭...

回答

99

時,爲您的使用情況下,我也注意到了我的職務重複的代碼,我認爲flatMap運算符是你所需要的:

this.userData.getUserPhotos('123456').flatMap(data => { 
    this.userPhotos = data; 
    return this.userData.getUserInfo(); 
}).subscribe(data => { 
    this.userInfo = data; 
}); 

這種方式,你會一旦收到第一個請求就執行第二個請求。當您想要使用前一個請求(前一個事件)的結果執行另一個時,運算符flatMap特別有用。不要忘了導入操作員能夠使用它:

import 'rxjs/add/operator/mergeMap'; 

這個答案可以給你更多的細節:

如果你只想使用subscribe方法,你使用類似的東西:

this.userData.getUserPhotos('123456') 
    .subscribe(
     (data) => { 
     this.userPhotos = data; 

     this.userData.getUserInfo().subscribe(
      (data) => { 
      this.userInfo = data; 
      }); 
     }); 

要完成,如果你想在並行執行兩個請求,當所有的結果則通知,你應該考慮使用Observable.forkJoin(需要添加import 'rxjs/add/observable/forkJoin'):

Observable.forkJoin([ 
    this.userData.getUserPhotos(), 
    this.userData.getUserInfo()]).subscribe(t=> { 
    var firstResult = t[0]; 
    var secondResult = t[1]; 
}); 
+0

但我得到的錯誤「 TypeError:source.subscribe不是[null]中的函數' –

+0

你在哪裏有這個錯誤?當調用'this.userData.getUserInfo()'? –

+0

從'Observable.forkJoin' –

相關問題