skip to Main Content

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.

3

Answers


  1. 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);
      }
    
    Login or Signup to reply.
  2. 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());
    }
    
    Login or Signup to reply.
  3. Try this

    getImagesForChosenRestaurant(id: string): Observable<string[]> {
      const imageRef = ref(storage, `food/${id}`);
      return from(listAll(imageRef)).pipe(
        switchMap((res) => forkJoin(res.items.map(getDownloadURL)))
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search