коллекция угловых огней дочерних узлов - PullRequest
0 голосов
/ 09 октября 2018

Я использую Angular и Google FireStore для хранения списка «заказов».Каждый заказ имеет список «товаров».Как я могу получить один наблюдаемый массив продуктов, который сведен со всех «заказов», которые полностью заполняют наш запрос?

Данные выглядят так:

[
{
  id: "item1",
  products: [
    { product1... }, {product2... }
  ]
},
{
  id: "item2",
  products: [
    { product3...}, {product2... }
  ]
}
]

конечный результат должен бытьнаблюдаемый список продуктов:

[{product1...}, {product2...}, {product3...}, {product2...}]

Я пытался использовать flatMap, но не могу заставить его правильно работать с результатом запроса AngularFire.Мое текущее "испытание" работает довольно далеко и выдает единый список "продуктов".Проблема в том, что он имеет «продукты» только из последнего «заказа».

Вот что у меня сейчас:

return this.db.collection<Order>('orders', ref => ref.where('status', '==', 3))
  .snapshotChanges()
  .pipe(
    flatMap(orders=> {
      return orders.map(a => {
          const order = a.payload.doc.data() as Order;
          return order.products;
        })}))

Я знаю, что схема ужасна и «продукты»должно быть в его собственной коллекции, но я не могу ее контролировать: (

Пожалуйста, помогите:)

Ответы [ 4 ]

0 голосов
/ 11 октября 2018

Спасибо всем за ваше время и усилия, я искренне ценю это.

Это то, чем я закончил, к сожалению, это не "чувствует" правильно, но работает.

flatMap(orders=> {
 let products = [];
 orders.map(a => {
  const order = a.payload.doc.data() as Order;
  order.products.map(product => products.push(product));
 })
 return of(products);
}))
0 голосов
/ 10 октября 2018

Это способ использования reduce.

const myArrayOfArrays = [
  [{id: 1, name: 'a'}, {id: 2, name: 'b'}, {id: 3, name: 'c'}],
  [{id: 10, name: 'x'}, {id: 20, name: 'y'}, {id: 30, name: 'z'}],
  [{id: 100, name: 'ax'}, {id: 200, name: 'by'}, {id: 300, name: 'cz'}],
]
of(myArrayOfArrays).pipe(
  map(myArrayOfArrays => myArrayOfArrays
    .reduce(
      (acc, val) => acc.concat(val), []
    ))
)
.subscribe(console.log)
0 голосов
/ 10 октября 2018

без использования flatMap (и pipe), попробуйте это:

  return this.db.collection<Order>('orders', ref => 
                ref.where('status', '==', 3))
        .snapshotChanges()
        .map(orders => {
           return orders.map(a => {
                  const order = a.payload.doc.data() as Order;
                 return order;
                 });
           })
        .mergeMap(p => from(p.products));
0 голосов
/ 10 октября 2018

Что если вы используете map вместо flatMap?

flatMap, то в качестве параметра требуется функция, которая возвращает ObservableInput.Массив IS и ObservableInput и, в этом случае, flatMap преобразует массив в Observable, который испускает каждый элемент в массиве.

Поэтому ваш код

flatMap(orders=> {
  return orders.map(a => {
      const order = a.payload.doc.data() as Order;
      return order.products;
    })}))

возвращает Observable, которыйвыдает каждый элемент коллекции orders как отдельное уведомление.

Если вам нужен Observable, который выдает список продуктов, то есть, который выдает массив, то вы можете заменить flatMap на map.

...