Ali Maher
Ali Maher

Reputation: 261

angular fire/ firebase > fetch collection and for each document fetch its sub collection

I have a collection of markets each market has a collection of products .. I`m trying to make query to get them all .. I ended up with a solution but I got a hint on compineLatest at line 9 "@deprecated — Pass arguments in a single array instead".

I want to know if there is a better abroach and how to use compineLatest correctly.

  //#region fetch method
  private fetch(marketsRef: AngularFirestoreCollection<Market>) {
    return marketsRef
      .snapshotChanges()
      .pipe(
        switchMap(markets => {
          if (!markets.length) {
            this._noDataSubject$.next(true);
          }
          return combineLatest([markets],
            combineLatest(
              markets.map(market => {
                return this.firestore.collection<MarketProduct>(`markets/${market.payload.doc.id}/products`, ref => {
                  return ref.orderBy('reviewResult')
                })
                  .snapshotChanges()
              })
            )
          )
        }), map(([markets, products]) => {
          const allProducts = products.reduce((acc, val) => acc.concat(val), []);
          const returnedMarkets = markets.map(market => {
            return {
              id: market.payload.doc.id,
              ...market.payload.doc.data() as Market,
              products: allProducts
                .filter(product => product.payload.doc.ref.path === `markets/${market.payload.doc.id}/products/${product.payload.doc.id}`)
                .map(product => {
                  return {
                    id: product.payload.doc.id,
                    ...product.payload.doc.data() as MarketProduct
                  }
                })
            }
          }) as MarketId[];
          return returnedMarkets;
        }))
  }
  //#endregion fetch method

  //#region fetch  new markets request
  fetchNewMarkets() {
    const key = `name.ar`;
    const marketsRef = this.firestore.collection<Market>('markets', ref => {
      return ref.where('reviewResult', '==', null).orderBy(key);
    });
    this.fetch(marketsRef)
      .subscribe(markets => {
        this._marketsChanges$.next(markets);
      })
  }
  //#endregion fetch new markets request

Upvotes: 0

Views: 166

Answers (2)

Ali Maher
Ali Maher

Reputation: 261

my end code

//#region fetch method
  private fetch(marketsRef: AngularFirestoreCollection<Market>) {
    return combineLatest([
      marketsRef.snapshotChanges(),
      marketsRef.snapshotChanges()
        .pipe(
          switchMap(markets => {
            if (!markets.length) {
              this._noDataSubject$.next(true);
            }
            return combineLatest(
              markets.map(market => {
                return this.firestore.collection<MarketProduct>(`markets/${market.payload.doc.id}/products`, ref => {
                  return ref.orderBy('reviewResult')
                })
                  .snapshotChanges()
              })
            )
          })

        )]).pipe(map(([markets, products]) => {
          const allProducts = products.reduce((acc, val) => acc.concat(val), []);
          return markets.map(market => {
            return {
              id: market.payload.doc.id,
              ...market.payload.doc.data() as Market,
              products: allProducts
                .filter(product => product.payload.doc.ref.path === `markets/${market.payload.doc.id}/products/${product.payload.doc.id}`)
                .map(product => {
                  return {
                    id: product.payload.doc.id,
                    ...product.payload.doc.data() as MarketProduct
                  }
                })
            }
          }) as MarketId[];
        }));
  }
  //#endregion fetch method

  //#region fetch  new markets request
  fetchNewMarkets() {
    const key = `name.ar`;
    const marketsRef = this.firestore.collection<Market>('markets', ref => {
      return ref.where('reviewResult', '==', null).orderBy(key);
    });
    this.fetch(marketsRef)
      .subscribe(markets => {
        this._newMarketsChanges$.next(markets);
      })
  }
  //#endregion fetch new markets request

Upvotes: 0

MoxxiManagarm
MoxxiManagarm

Reputation: 9124

return combineLatest([markets], combineLatest(/* ... */));

You have this line. You have 2 arguments for the first combineLatest. The signature combineLatest(...obs) is deprecated. All you need to do is to add your 2nd combineLatest into the array.

return combineLatest([markets, combineLatest(/* ... */)]);

Edit, additional suggestion

// const allProducts = products.reduce((acc, val) => acc.concat(val), []);
const allProducts = products.flat();

Upvotes: 1

Related Questions