【问题标题】:How to solve Observable<Observable<{...}>[ ]> to Observable<{...}[ ]>?如何解决 Observable<Observable<{...}>[ ]> 到 Observable<{...}[ ]>?
【发布时间】:2019-08-17 05:23:46
【问题描述】:

我正在尝试将两个可观察对象组合成一个可观察对象,因此我可以使用来自这两个对象的信息。可观察对象都是来自 NoSQL 数据库(Cloud Firestore 数据库)中两个不同集合的文档。两个集合共享一个具有相同值(uid 和 partnerID)的字段。我首先创建了一个查询来获取第一个可观察对象,这个查询返回一个Observable&lt;{Object1}[]&gt;。如果我尝试添加代码以获取第二个可观察对象并将其与现有对象结合,我会得到一个Observable&lt;Observable&lt;{Object1 merged with Object2}&gt;[]&gt;。

如何确保生成的 observable 是一个由对象组成的数组,这些对象是我从数据库中提取的这两个对象的组合?

我的目标是在我的 Angular 项目中使用组合的 observable 对象。我正在尝试使用 rxjs 运算符来实现这一点。

这是我的服务中没有第二个可观察对象的函数:

queryMatches(fieldNameOfRole, boolValueOfAccepted) {
    return this.authService.user$.pipe(
      switchMap(user => {
        return this.angularFirestore
          .collection('matches', ref => ref.where(fieldNameOfRole, '==', user ? user.uid : '')
            .where('accepted', '==', boolValueOfAccepted))
          .snapshotChanges()
          .pipe(
            map(actions => {
              return actions.map(a => {
                const data = a.payload.doc.data() as Match;
                const matchId = a.payload.doc.id;
                return { matchId, ...data };
              });
            })
          );
      })
    );
  }

这会产生以下返回:

(method) MatchStoreService.queryMatches(fieldNameOfRole: any, boolValueOfAccepted: any): Observable<{
    initiatorID: string;
    partnerID: string;
    matchedOffer: string;
    accepted: boolean;
    id: string;
}[]>

这就是我尝试将它与第二个可观察对象结合起来的方式:

queryMatches(fieldNameOfRole, boolValueOfAccepted) {
    return this.authService.user$.pipe(
      switchMap(user => {
        return this.angularFirestore
          .collection('matches', ref => ref.where(fieldNameOfRole, '==', user ? user.uid : '')
            .where('accepted', '==', boolValueOfAccepted))
          .snapshotChanges()
          .pipe(
            map(actions => {
              return actions.map(a => {
                const data = a.payload.doc.data() as Match;
                const matchId = a.payload.doc.id;
                return { matchId, ...data };
              });
            })
          );
      }),
      map(matches => {
        return matches.map(match => {
          return this.userStoreService.getUserById(match.partnerID).pipe(
            map(user => {
              return { ...match, ...user };
            })
          );
        });
      })
    );
  }

这会产生以下返回:

(method) MatchStoreService.queryMatches(fieldNameOfRole: any, boolValueOfAccepted: any): Observable<Observable<{
    uid: string;
    firstname: string;
    lastname: string;
    dateOfBirth: Date;
    sex: string;
    city: string;
    activities: string[];
    offers: string[];
    mail?: string;
    ... 4 more ...;
    matchId: string;
}>[]>

更新

我是如何实现 getUserById() 的:

getUserById(uid) {
    return this.angularFirestore
    .collection<any>(`users`)
    .doc<User>(uid).valueChanges();
   }

【问题讨论】:

  • 看起来您需要使用一些扁平化运算符,例如 mergeMap 而不是 map 以便获得值流而不是可观察对象流
  • 我也是这么想的,但是我应该在哪里使用女巫一号呢?我尝试了不同的组合,但没有任何效果。
  • 如果您从 map 的回调中返回 Observable - 您应该使用 mergeMap(也适用于数组)

标签: typescript rxjs observable


【解决方案1】:

只需像这样使用 forkJoin 运算符

 map(matches => {
        return combineLatest(matches.map(match => {
          return this.userStoreService.getUserById(match.partnerID).pipe(
            map(user => {
              return { ...match, ...user };
            })
          );
        }));
      })

【讨论】:

  • 我按照你说的改了,但是不得不把第一张地图改成switchMap,然后return改成Observable&lt;{Object1}[]&gt; 。但出于某种原因,如果我在该方法上调用 subscribe(),我不会得到任何结果。
  • 直到最后一行,我所有的 console.log() 都在工作,甚至还给了我的组合对象,但如果我尝试 subscribe() 它,它不会给我任何结果。甚至我的 subscribe() 中的 console.log() 都不起作用
  • @ConstantinBeer this.userStoreService.getUserById 完成了吗? forkJoin 中的所有 Observables 都必须完成。
  • @fridoo 我添加了this.userStoreService.getUserById的实现。我的user 的console.log() 给了我用户文档的信息。所以我认为它已经完成了还是还有其他事情要做?
  • @ConstantinBeer,forkJoin 在发出值之前等待所有源完成,但是在 getUserById 中返回 valueChanges()。正因为如此 - 它永远不会完成。如果您想获得这些流提供的所有更新,请将我的答案中的forkJoin 替换为combineLatest。如果你只想要一个值,那么要么让你的 getUserById 方法返回一个值,要么使用zip(observables).pipe(first())
猜你喜欢
  • 2019-08-24
  • 1970-01-01
  • 2018-06-06
  • 2018-10-23
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 2021-06-25
相关资源
最近更新 更多