使用TypeScript从Angular2中的http数据链接RxJS Observables [英] Chaining RxJS Observables from http data in Angular2 with TypeScript

查看:76
本文介绍了使用TypeScript从Angular2中的http数据链接RxJS Observables的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去四年中愉快地使用AngularJS 1. *之后,我目前正在尝试自学Angular2和TypeScript!我必须承认我很讨厌它,但是我确定我的尤里卡时刻就在眼前...无论如何,我已经在我的虚拟应用程序中编写了一项服务,该服务将从我编写的提供JSON的电话后端获取http数据. /p>

I'm currently trying to teach myself Angular2 and TypeScript after happily working with AngularJS 1.* for the last 4 years! I have to admit I am hating it but I am sure my eureka moment is just around the corner... anyway, I have written a service in my dummy app that will fetch http data from a phoney backend I wrote that serves JSON.

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中,这很容易,因为在我的控制器中,我会像这样避免厄运金字塔" ...

Now in a Component I wish to run (or chain) both getUserInfo() and getUserPhotos(myId) methods. In AngularJS this was easy as in my controller I would do something like this to avoid the "Pyramid of doom"...

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

现在我已经尝试在组件中执行类似的操作(将.then替换为.subscribe),但是我的错误控制台发疯了!

Now I have tried doing something similar in my component (replacing .then for .subscribe) however my error console going crazy!

@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标头时,我也注意到函数中重复的代码...

I'm obviously doing something wrong... how would I best with Observables and RxJS? Sorry if I am asking stupid questions... but thanks for the help in advance! I have also noticed the repeated code in my functions when declaring my http headers...

推荐答案

对于您的用例,我认为flatMap运算符就是您所需要的:

For your use case, I think that the flatMap operator is what you need:

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

这样,您将在收到第一个请求后执行第二个请求.当您要使用上一个请求(上一个事件)的结果来执行另一个请求的结果时,flatMap运算符特别有用.不要忘记导入运算符以能够使用它:

This way, you will execute the second request once the first one is received. The flatMap operator is particularly useful when you want to use the result of the previous request (previous event) to execute another one. Don't forget to import the operator to be able to use it:

import 'rxjs/add/operator/flatMap';

此答案可以为您提供更多详细信息:

This answer could give you more details:

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆