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