Emanuel Agnelli
Emanuel Agnelli

Reputation: 53

Firebase getDownloadURL push into array

I've been trying to solve this issue for a few days and I can't figure it out. In my defense, I started playing around with javascript a month ago, so I don't have much experience. Here's the problem:

I want to loop over a storage folder, get all the url's in there into an array outside the promise and then work with that array to display thumbnail and link to the original image. This is my code:

function promiseResolve(imgNameArray, user) {
return new Promise((resolve, reject) => {
    console.log(params['patient'], params['treatment'])
    var storageRef = storage.ref(`${user.uid}/${params['patient']}/${params['treatment']}`)
    storageRef.listAll().then(result => {
        result.items.forEach(imgRef => {
                // Extract file names
            imgRef.getDownloadURL().then(url => {
                    imgNameArray.push(url);
                })
        })
        resolve(imgNameArray);
    })
})}

Then i would take the promise and resolve it like this:

if (user) {
    let linkArray = []
    promiseResolve(linkArray, user).then(arr => {
            // Work with the array
        })}

But the array returned is empty... I know it has something to do with the fact that all the promises are not resolved, but i can't figure why or how to manage it... the only thing is that, if i move the resolve(imgNameArray) inside the getDownloadURL().then() the array is resolved, but only returns 1 value (the first one).

Any ideas? Thanks in advance

Upvotes: 0

Views: 488

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

The getDownloadURL() method you call is asynchronous. This means that right nwo your resolve(imgNameArray); runs before imgNameArray.push(url) is ever called.

If you want to resolve with all download URLs, you have to wait until all promises are resolved:

function promiseResolve(imgNameArray, user) {
return new Promise((resolve, reject) => {
    console.log(params['patient'], params['treatment'])
    var storageRef = storage.ref(`${user.uid}/${params['patient']}/${params['treatment']}`)
    storageRef.listAll().then(result => {
        const promises = result.items.map(imgRef => imgRef.getDownloadURL())
        Promise.all(promises).then((imgNameArray) => {
            resolve(imgNameArray);
        });
    })
})}

The above can (as far as I can see) be simplified to:

function promiseResolve(user) {
    var storageRef = storage.ref(`${user.uid}/${params['patient']}/${params['treatment']}`)
    return storageRef.listAll().then(result => {
        return Promise.all(result.items.map(imgRef => imgRef.getDownloadURL()));
    })
}

That you'd then call with:

promiseResolve(user).then(imgNameArray => {
  ...
});

Upvotes: 2

Related Questions