объединить 2 наблюдаемые - PullRequest
0 голосов
/ 30 мая 2019

Я использую Firestore в качестве базы данных и использую angularfire2 для извлечения данных из него. У меня есть коллекция комментариев, в которой каждый комментарий хранит идентификатор пользователя. Я хочу получить информацию о пользователе, такую ​​как user 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 };
});

Приведенный выше код не смог достичь того, что я хочу. По сути, он читает идентификатор пользователя из каждого комментария, а затем использует этот идентификатор пользователя, чтобы найти информацию о соответствующем пользователе, и объединяет их вместе в результирующий поток. Комментарии $ observable работает правильно. Пользователи $ observable не работали. Кроме того, я не уверен, является ли zip правильным вариантом в этом случае.

Ответы [ 2 ]

0 голосов
/ 30 мая 2019

Я думаю, что вы ищете больше ОбъединитьПоследний вместо почтового индекса.Поскольку каждый раз, когда генерируется один поток, вам нужно пересчитывать выходной поток.

Функция слияния тоже кажется не очень хорошей. Если я правильно понял, вы должны объединить каждый комментарий с его пользователем, для этого вы можете простоdo:

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>

Надеюсь, это поможет!

0 голосов
/ 30 мая 2019

Кажется, вы пропустили имя коллекции для пользователей .Вторая строка.

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.

...