typescript - 使用 TypeScript 从 Angular2 中的 http 数据链接 RxJS Observables

标签 typescript angular observable rxjs

在愉快地使用 AngularJS 1.* 过去 4 年之后,我目前正在尝试自学 Angular2 和 TypeScript!我不得不承认我讨厌它,但我确信我的灵光一现的时刻即将到来......无论如何,我已经在我的虚拟应用程序中编写了一个服务,它将从我编写的服务于 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 中这很容易,因为在我的 Controller 中我会做这样的事情来避免“厄运金字塔”......

// 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 header 时,我还注意到函数中的重复代码...

最佳答案

对于您的用例,我认为 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;
          });
      });

最后,如果您希望并行执行两个请求并在所有结果出现时得到通知,您应该考虑使用 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];
});

关于typescript - 使用 TypeScript 从 Angular2 中的 http 数据链接 RxJS Observables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35268482/

相关文章:

javascript - 为什么我在 TypeScript 中收到错误 cannot redeclare block-scoped variable 'name'?

javascript - 使用具有可选属性的对象循环遍历数组,但始终完全循环

Visual Studio Code 中 HTML 组件中的 Angular 10 “No definition found for …”

angular - Angular 编译器需要 TypeScript >=3.4.0 和 <3.5.0,但找到了 3.5.3

angular - 在 typescript 中查找键值最小的对象

forms - Angular2 可编辑表单以及使用 Observables 的服务

javascript - '[object 对象],[object 对象 ]' for pipe ' AsyncPipe'

java - 对象中的可观察列表和嵌套列表

Angular 4 - 拦截http请求并在登录后重新发送

angular - 使用 Angular 中的 RxJs,我只需要完成在组件中创建的 Observables 吗?