Home > OS >  Angular RxJS multiple Firebase calls to map a single Observable
Angular RxJS multiple Firebase calls to map a single Observable

Time:11-04

I can't find the way to get this code working.

I want to get a list of products from firestore and for each one of them I have to make another call that returns that product URL.

I tried the following but of course I obtain an Observable in the new product property:

fillShopWithProducts(): void {
this.productsOb = this.productsService.getProducts()
.pipe(
  take(1), 
  switchMap(
    (products:Product[]) => {
      let newArrayOfProducts = products.map((product:Product) =>
       {
        return {
          ...product,
          imgUrlChanged:this.getProductUrl(product)
        }
       });           
       return newArrayOfProducts;     
    }),    
  finalize(()=> {
    this.shopIsLoading = false;       
  })
);    

Here is the function that returns an Observable with the Product URL:

getProductUrl(product:Product): Observable<string> { 
  const ref = this.angularFireStorage.ref(`shopImages/${product.imgUrl}`);
  return ref.getDownloadURL();
}

Thanks in advance for any help.

CodePudding user response:

Instead of just mapping the products array to an array containing the observable, you should use forkJoin in order to wait for all observables to complete before mapping the result to the enriched version of the product:

function fillShopWithProducts(): void {
  this.productsOb = this1.productsService
    .getProducts()
    .pipe(
      take(1),
      switchMap((products: Product[]) =>
        forkJoin(
          products.map((product) =>
            this
              .getProductUrl(product)
              .pipe(
                map((productUrl) => ({ ...product, imgUrlChanged: productUrl }))
              )
          )
        )
      ),
      finalize(() => {
        this.shopIsLoading = false;
      })
    )
}
  • Related