使用TypeScript链接Angular2中http数据的RxJS观测值

使用TypeScript链接Angular2中http数据的RxJS观测值,typescript,angular,observable,rxjs,Typescript,Angular,Observable,Rxjs,在与AngularJS 1*愉快地合作了4年之后,我目前正尝试自学Angular2和打字脚本。*!我不得不承认我讨厌它,但我确信我的尤里卡时刻就在眼前。。。无论如何,我已经在我的虚拟应用程序中编写了一个服务,它将从我编写的提供JSON服务的假后端获取http数据 import {Injectable} from 'angular2/core'; import {Http, Headers, Response} from 'angular2/http'; import {Observable} f

在与AngularJS 1*愉快地合作了4年之后,我目前正尝试自学Angular2和打字脚本。*!我不得不承认我讨厌它,但我确信我的尤里卡时刻就在眼前。。。无论如何,我已经在我的虚拟应用程序中编写了一个服务,它将从我编写的提供JSON服务的假后端获取http数据

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中,这很容易,因为在我的控制器中,我会这样做以避免“末日金字塔”

现在我尝试在我的组件中做一些类似的事情(替换
。然后为
。订阅
)替换
),但是我的错误控制台快疯了

@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;
            });
    }

}

我显然做错了什么。。。如何最好地使用Observable和RxJS?对不起,如果我问了一些愚蠢的问题。。。但是提前谢谢你的帮助!我还注意到在声明我的http头时函数中重复的代码…

对于您的用例,我认为
flatMap
操作符是您所需要的:

this.userData.getUserPhotos('123456').flatMap(data => {
  this.userPhotos = data;
  return this.userData.getUserInfo();
}).subscribe(data => {
  this.userInfo = data;
});
这样,您将在收到第一个请求后执行第二个请求。当您想要使用上一个请求(上一个事件)的结果来执行另一个请求时,
flatMap
操作符特别有用。不要忘记导入操作员以便能够使用它:

import 'rxjs/add/operator/flatMap';
此答案可以为您提供更多详细信息:

如果您只想使用
subscribe
方法,您可以使用类似的方法:

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

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

完成,如果您想并行执行这两个请求,并且在所有结果都被通知时,您应该考虑使用<代码>可观察到。FokCuin < /C>(需要添加<代码>导入Rxjs/Addiaby/Vistue/FokCuin < /COD>):


但是,我确实收到了错误“TypeError:source.subscribe不是[null]中的函数”,您在哪里遇到此错误?当调用
this.userData.getUserInfo()时
?噢!我的回答中有一个输入错误:
this.userData.getUserPhotos(),this.userData.getUserInfo()
而不是
this.userData.getUserPhotos,this.userData.getUserInfo()
。很抱歉为什么是平面图?为什么不切换地图?我假设如果最初的GET请求突然为User输出了另一个值,那么您就不想继续获取User的前一个值的图像。如果有人看到这一点并想知道它为什么不起作用:在rxjs6中,import和forkJoin语法发生了轻微的变化。现在需要从“rxjs”添加
import{forkJoin}
导入函数。此外,forkJoin不再是Observable的成员,而是一个单独的函数。因此,它不是
Observable.forkJoin()
而是
forkJoin()
this.userData.getUserPhotos('123456')
    .subscribe(
      (data) => {
        this.userPhotos = data;

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