结合2个可观察物

时间:2019-05-30 12:10:30

标签: rxjs angularfire2

我正在使用Firestore作为数据库,并使用angularfire2从中检索数据。 我有一个注释集合,其中每个注释都存储一个用户ID。我想要获取用户信息(例如用户displayName和photoURL),然后将其与原始评论流组合以产生包含评论信息和用户信息的流。我尝试将评论和用户流合并如下:

const comments$ = this.afs.collection(`comments`).valueChanges();
const users$ = this.afs.collection(`comments`).valueChanges().pipe(
  switchMap((comments) => {
    return comments.map(comment => this.afs.doc(`users/${comment.uid}`).valueChanges());
  })
);
const combine = zip(comments$, users$, (comments, users) => {
  return {...comments, ...users };
});

以上代码未能实现我想要的。本质上,它从每个注释中读取用户ID,然后使用该用户ID查找相关的用户信息,并将它们组合在一起作为结果流。可观察到的comments $正常工作。可观察到的用户无效。另外,我不确定在这种情况下zip是否适合使用。

2 个答案:

答案 0 :(得分:0)

您似乎错过了用户的集合名称。第二行。

const comments$ = this.afs.collection(`comments`).valueChanges();
const users$ = this.afs.collection(/** HERE?? **/).valueChanges().pipe(
  switchMap((comments) => {
    return comments.map(comment => this.afs.doc(`users/${comment.uid}`).valueChanges());
  })
);
const combine = zip(comments$, users$, (comments, users) => {
  return {...comments, ...users };
});

这似乎也不起作用,因为在必须中返回switchMap内部的可观察值。

答案 1 :(得分:0)

我认为您正在搜索 combineLatest 而不是zip。由于每次发射一个流,您都需要重新计算输出流。

合并功能似乎也不好,如果我理解得很好,则必须将每个注释与其用户一起加入,为此,您可以执行以下操作:

comments.map((comment) => {
      return {
          ...comment,
          user: users.find(user => user.id === comment.user_id)}
   })

这是一个简单的代码段,其中两个流都以这种方式连接在一起,最终结果是带有用户信息的评论数组

function mockUsers$() {
  return rxjs.of([
  {id: '1', name: 'user1'},
  {id: '2', name: 'user2'},
  {id: '3', name: 'user3'}
]);
}

function mockComments$() {
  return rxjs.of([
  {id: '1', user_id: '1', comment: 'user1 comment 1'},
  {id: '2', user_id: '1', comment: 'user1 comment 2'},
  {id: '3', user_id: '1', comment: 'user1 comment 3'},
  {id: '4', user_id: '2', comment: 'user2 comment'},
  {id: '5', user_id: '3', comment: 'user3 comment 1'},
  {id: '6', user_id: '3', comment: 'user3 comment 2'}]);
}

const comments$ = mockComments$();
const users$ = mockUsers$()

rxjs.combineLatest(users$, comments$, (users, comments) => comments.map((comment) => {
      return {
          ...comment,
          user: {...users.find(user => user.id === comment.user_id)}}
   })   
).subscribe((data) => console.log('Comments with user info: ', data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.2/rxjs.umd.js"></script>

希望这会有所帮助!

相关问题