Home > OS >  Service returns empty array
Service returns empty array

Time:09-14

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.

CodePudding user response:

try this:

  async getImagesForChosenRestaurant(id: string): Promise<void> {
    this.imageList = []
      this.imageRef = ref(storage, `food/${id}`)
      const list = await listAll(this.imageRef);
      list.items.forEach(async item => {
          const url = await getDownloadURL(item);
          this.imageList.push(url);
      })
      return of(this.imageList);
  }

CodePudding user response:

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());
}
  • Related