使用RxJS .flatmap在Angular2中组合两个可观察流

时间:2016-06-20 09:28:17

标签: typescript angular rxjs

我在Angular2应用程序中编写了一个服务中的Observable(称为ContentService),看起来像这样(我已经编辑了这个/减少了内容以便于阅读):

@Injectable()
export class ContentService {

    constructor(private http:Http, private apiService:ApiService) {

        this.content = this.http.get('src/i18n/en.json')
            .map((res:Response) => {
                let json: {} = res.json();
                return mapData(json);
            })

        mapData() {
            // function stuff to format data
        }

现在,我希望调用我注入的apiService,这将返回一个JSON对象,其结构与this.content生成的结构相同。请注意,this.content来自本地json文件,apiStream来自第三方API / http源。我需要将apiService的结果连接(或添加)到this.content observable。我认为flapMap是解决这个问题的最佳方法,但是我犯了一些语法错误(如果我正确的方法)。我正在考虑添加像这样的新内容

this.content = this.http.get('src/i18n/' + this.userLang + '.json')
            .map((res:Response) => {
                let json: {} = res.json();
                return mapData(json);
            })
            .flatMap(() => {
                apiService.getAllCurrentListings().subscribe(response => {
                    return mapData(response);
                })
            });

然而,这会产生错误,所以我显然做错了。我是否应该调用我的API服务,就像不在.flapMap时那样我得到了我想要的数据,所以我显然犯了语法错误。如何将apiService数据添加到原始this.content调用结果中?

非常感谢提前。

2 个答案:

答案 0 :(得分:1)

这就是我提出的解决方案:

this.content = Observable.forkJoin(
            this.http.get('src/i18n/en.json').map((res:Response) => res.json()),
            apiService.getAllCurrentListings()
        ).map(res => {
            let tempJson:{} = Object.assign(res[0], res[1]);
            return mapData(tempJson);
        })

答案 1 :(得分:0)

this.content应包含哪些数据?

在你的代码中,它可以从this.http.get中获取和观察。如果你想获得http数据响应,你应该这样做。



Injectable()
export class ContentService {

    constructor(private http:Http, private apiService:ApiService)     {

        his.http.get('src/i18n/en.json')
            .map((res:Response) => {
                let json: {} = res.json();
                return mapData(json);
            })
            .subscribe(mappedData => 
                      this.content = mappedData)

        mapData() {
            // function stuff to format data
        }
    }      




话虽如此,你可以想象你的第二个片段也是错误的。 但是在这种情况下我不会使用flatMap运算符,因为我知道apiService.getAllCurrentListings对第一个http调用没有数据依赖性。因此,forkJoin操作符可以做到这一点。



import {Observable} from 'rxjs/Observable'

Observable.forkJoin([
  this.http.get('src/i18n/' + this.userLang + '.json'),
  this.apiService.getAllCurrentListings()])
  .map(res => {
    this.content = this.mapData(res[0].json())
    /* again, I dind't get what this.content is supposed to hold, but we need a different variable to store the second result */
    this.content2 = this.mapData(res[1].json())
  })
  




.forkJoin对数组结构中的Observable进行分组,因此必须相应地使用数组索引读取每个响应。

如果这不是您所需要的,请提供this.content定义及其应存储的内容。