Rxjs:将数据添加到从http响应返回的数组元素

时间:2016-12-06 13:07:29

标签: http angular typescript rxjs observable

关注此问题:Add data to http response using rxjs

我已经尝试将此代码改编为我的用例,其中第一个http调用的结果产生数组而不是值......但我无法理解它。 如何在rxjs(Typescript)中编写以下伪代码?

致电我的服务器

获取具有以下属性的对象数组:(外部标识,名称)

对于每个对象,调用另一个传递外部标识的服务器

对于来自外部服务器的每个响应,获取另一个对象并将其部分属性合并到具有相同id的服务器的对象中

最后,订阅并获取具有以下结构的增强对象数组:(外部id,名称,增强prop1,增强prop2,...)

到目前为止,我唯一能做的就是:

    this._appService
        .getUserGames()
        .subscribe(games => {
            this._userGames = _.map(games, game => ({ id: game.id, externalGameId: game.externalGameId, name: game.name }));
            _.forEach(this._userGames, game => {
                this._externalService
                    .getExternalGameById(game.externalGameId)
                    .subscribe(externalThing => {
                        (<any>game).thumbnail = externalThing.thumbnail;
                        (<any>game).name = externalThing.name;
                    });
            });
        });

提前致谢

2 个答案:

答案 0 :(得分:1)

我找到了让它发挥作用的方法。我会对代码进行评论,以便更好地解释它的作用,特别是对我自己:D

this._appService
        .getUserGames() // Here we have an observable that emits only 1 value: an any[]
        .mergeMap(games => _.map(games, game => this._externalService.augmentGame(game))) // Here we map the any[] to an Observable<any>[]. The external service takes the object and enriches it with more properties
        .concatAll() // This will take n observables (the Observable<any>[]) and return an Observable<any> that emits n values
        .toArray() // But I want a single emission of an any[], so I turn that n emissions to a single emission of an array
        .subscribe(games => { ... }); // TA-DAAAAA!

答案 1 :(得分:0)

不要使用subscribe。请改用map。 无法测试,但看起来应该更像这样:

this._appService
    .getUserGames()
    .map(games => {
        this._userGames = _.map(games, game => ({ id: game.id, externalGameId: game.externalGameId, name: game.name }));
        return this._userGames.map(game => { /* this should return an array of observables.. */
            return this._externalService
                .getExternalGameById(game.externalGameId)
                .map(externalThing => {
                    (<any>game).thumbnail = externalThing.thumbnail;
                    (<any>game).name = externalThing.name;
                    return game;
                });
        });
    })
    .mergeAll()
    .subscribe(xx => ...); // here you can subscribe..