[FIXED] Service returns empty array

Issue

I am working on a personal project and I have a service that returns an array of images from firebases storage. The problem is that when I subscribe to the observable I get an empty array. When I open the array all the data is there. The problem is when I try to do something with the array I get undefined (for example console.log(myArray[0]) is undefined). If I’m correct the problem is that observable are asynchronous and that is why I get the empty array. My question is, how can I fix this problem?

Here is the service

  getImagesForChosenRestaurant(id: string): Observable<any> {
    this.imageList = []
      this.imageRef = ref(storage, `food/${id}`)
      listAll(this.imageRef).then(res => {
        res.items.forEach(item => {
          getDownloadURL(item).then(url => {
            this.imageList.push(url);
          })
        })
      })
      return of(this.imageList);
  }

And here is the subscription

  ngOnInit(): void {
    this.route.params.subscribe(params => {
      this.restaurantService.getImagesForChosenRestaurant(params['id']).subscribe((foodPic: any) => {
        this.foodImages = foodPic;
      })
    })
  }

Thank you for any answer.

Solution

You can use .map method to convert your array of items from listAll to array of promises for getDownloadURL. After that just use Promise.all() with rxjs from.

import { from, Observable } from "rxjs";
import { ref, listAll, getDownloadURL } from "firebase/storage";

getImagesForChosenRestaurant(id: string): Observable<string[]> {
  const wrapperFn = async () => {
    const imageRef = ref(storage, `food/${id}`);
    const listAllResult = await listAll(imageRef);
    const imagesDownloadUrlsPromises = listAllResult.items.map((item) =>
      getDownloadURL(item)
    );
    return Promise.all(imagesDownloadUrlsPromises);
  };
  return from(wrapperFn());
}

Answered By – Sergey Sosunov

Answer Checked By – David Marino (FixeMe Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *