可观察数组的可观察对象?

时间:2019-04-19 02:15:50

标签: angular rxjs google-cloud-firestore observable

我有一个具有两个属性的Firestore文档,它们都是Firestore数据库中其他位置的<Game>{}个不同对象的ID的数组。

我有什么办法创建一个可观察对象,该对象将流传输一个包含两个单独的数组的对象,这些数组由这些id代表?

我不认为有一种方法可以只拥有一个单一的对象流,因为(一旦我订阅),由于数组大小不是恒定的,我不知道哪个项目属于哪个数组。

我是Observable和rxjs的新手,并且经常阅读有关不同的运算符的信息,但是我有点被困在这里,如果找不到解决方案,我就打算重组我的数据。

现在,我的服务类中有类似的内容,但是它不能像我订阅该函数时那样工作。

  getPlayerGames(uid: string) {
    return this._db.doc<PlayerGameSession>(`users/${uid}/mygamesession/games`).valueChanges().pipe(
      map(gameObj => {
        let combined1;
        let combined2;

        if (gameObj.prop1) {
          const prop1Streams = gameObj.prop1.map(
            gameId => this._db.doc<Game>(`games/${gameId}`).valueChanges()
          );

          combined1 = combineLatest(...prop1Streams);
        }

        if (gameObj.prop2) {
          const prop2Streams = gameObj.prop2.map(
            gameId => this._db.doc<Game>(`games/${gameId}`).valueChanges()
          );

          combined2 = combineLatest(...prop2Streams);
        }

        return combineLatest(combined1, combined2);

      }),
      switchMap(([c1, c2]) => of({ c1: c1, c2: c2 }))
    );
  }

1 个答案:

答案 0 :(得分:1)

您要从可观察的类型中返回具有两个属性的对象的可观察对象,如果要返回具有两个数组的对象的可观察对象与数据,则需要将数组可观察的对象组合在一起,如下例所示:

const v1 = new BehaviorSubject('1')
const v2 = new BehaviorSubject('2')
const v3 = new BehaviorSubject('3')
const v4 = new BehaviorSubject('4')

const combined1 = combineLatest(v1, v2)
const combined2 = combineLatest(v3, v4)

const combined3 = combineLatest(combined1, combined2)

combined3
  .pipe(switchMap(([c1, c2]) => of({c1: c1, c2: c2})))
  .subscribe(console.log)

在此示例中,我将四个可观察的对象合并为两个数组,然后将这些数据合并为两个对象的组合对象

尝试此代码:

getPlayerGames(uid: string) {
    return this._db.doc<PlayerGameSession>(`users/${uid}/mygamesession/games`).valueChanges().pipe(
  switchMap(gameObj => {
    let combined1 = of([]);
    let combined2 = of([]);;

    if (gameObj.prop1) {
      const prop1Streams = gameObj.prop1.map(
        gameId => this._db.doc<Game>(`games/${gameId}`).valueChanges()
      );

      combined1 = combineLatest(...prop1Streams);
    }

    if (gameObj.prop2) {
      const prop2Streams = gameObj.prop2.map(
        gameId => this._db.doc<Game>(`games/${gameId}`).valueChanges()
      );

      combined2 = combineLatest(...prop2Streams);
    }

    return combineLatest(combined1, combined2)
       .pipe(switchMap(([c1, c2]) => of({c1: c1, c2: c2}))

  })
);

}