Angular Комбайн FirestoreLatest с несколькими запросами - PullRequest
0 голосов
/ 17 апреля 2020

У меня небольшие проблемы с Angular9, Firestore6 и оператором combineLatest rx js.

У меня одна коллекция users и другая коллекция items. У одного пользователя может быть несколько элементов, но по старинке, во многих отношениях, так как элементы являются основными данными (неизменяемыми), а таблица мостов объединяет обе коллекции с дополнительными данными:

  • предметы

    • яблоко
      • название: "яблоко"
      • цвет: "зеленый"
  • user

    • items
      • uid
        • uid: "яблоко"
        • количество: 23

Поэтому мне нужно получить список предметов вошедших в систему user, объединяющих обе коллекции:

  • user
    • items
      • uid
        • uid: "apple"
        • количество: 23
        • join
          • name: "яблоко"
          • цвет: "зеленый"

Это мой код:

import { AngularFireAuth } from '@angular/fire/auth';
import { AngularFirestore } from '@angular/fire/firestore';
import { switchMap, map } from 'rxjs/operators';
import { combineLatest, of } from 'rxjs';

getUserItems() {
  return this.angularFireAuth.authState.pipe(
    switchMap(user => {
      if (user) {
        return this.angularFirestore.collection<any>(`users/${user.uid}/items`).valueChanges()
          .pipe(
            switchMap(userItems=> {
              return combineLatest([
                of(userItems),
                userItems.map(userItem=> this.angularFirestore.doc<any>(`items/${userItem}`).valueChanges())
              ])
            }),
            map(([userItems, items]) => {
              console.log(userItems, items);
              return userItems.map(userItem => {
                return {
                  ...userItem,
                  join: items.find(item => item.uid === userItem.uid)
                }
              })
            })
          )
      }
    })
  )
}

Но в map(([userItems, items]) вместо [any[], any[]] я получаю [any[], Observable<any>], он не компилируется, потому что Property 'find' does not exist on type 'Observable<any>'.

Я полагаю, Это потому, что второй .valueChanges() не разрешается, но я не знаю, что я делаю неправильно. Кто-нибудь может мне помочь?

Я уже пробовал другие ответы, такие как этот , но пока безуспешно.

Заранее спасибо.

1 Ответ

0 голосов
/ 17 апреля 2020

Вы были очень близки, вам просто нужно добавить оператор распространения к userItems.map, и вам нужно получить itemId (только предположение) от объекта userItem:

return combineLatest([
  of(userItems),
  ...userItems.map(
    userItem => this.angularFirestore.doc<any(`items/${userItem.itemId}`).valueChanges()
  )
])

combineLatest хочет массив Observables. Давайте проигнорируем of(userItems) Если вы просто выполните:

combineLatest([
  userItems.map((userItem) => this.af.valueChanges())
]) 

В результате вы получите массив внутри массива, поэтому в основном Observable[][]. Вот почему вам нужно использовать оператор распространения, чтобы поместить элементы в окружающий массив. Если у вас не было of(userItems), вы могли бы просто сделать:

combineLatest(
  userItems.map((userItem) => this.af.valueChanges())
) 

То есть без массива-обертки, но поскольку вам также нужен userItems, это хорошее решение, чтобы добавить их в верх.

Однако я заметил пару других ошибок, которые, вероятно, не помогут вам. items на последней карте - это всего лишь один элемент, а не массив. Чтобы получить его в ожидаемый массив, вам снова нужно использовать оператор распространения, который в данном случае является оператором покоя, для параметра items, например:

map(([userItems, ...items]) => {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...