Regan
Regan

Reputation: 23

Javascript Array Not Working within Another Function (No error reported)

My array would not work as expected when items are added within a Firebase function. However, it works outside of the Firebase function.

test() is the function called to add a "sample" string into myList Array.

<script type="text/javascript">
// Firebase scripts
...

var myList = [];

// Firebase storage function. There are 6 items in res.items. Expected myList.length = 6.
res.items.forEach(function (itemRef, index) {
    itemRef.getMetadata().then(function (metadata) {
        test();
    }).catch(function (error) {
        console.log(error);
    });
});


function test(){
    myList.push("sample");
}
console.log(Array.isArray(myList)); // Returned *true* as expected.
test();
test();
console.log(myList.length); // Returned 2 instead of 8 (2 + 6 items from *Firebase* function).
console.log(myList); // Returned the Array with 8 items.
console.log(myList.length); // Still returned 2 instead of 8 (2 + 6 items from *Firebase* function).

...
</script>

The weirdest part: In browser DevTools, console.log(myList.length); returned 8 as expected. No error is reported in the console. Please view screenshots for better understanding.

Thank you very much.

Firefox Developer Tools screenshot

Chrome DevTools screenshot

Upvotes: 1

Views: 55

Answers (2)

Unmitigated
Unmitigated

Reputation: 89412

This is because itemRef.getMetadata() is asynchronous and your console.log is executing before the data is obtained. You may want to use an asynchronous function and await.

(async ()=>{
    var myList = [];
    for(const itemRef of items){
      const data = await itemRef.getMetadata();
      test();
    }
    //log...
})();

Alternatively, perform logging in the .then callback:

itemRef.getMetadata().then(function (metadata) {
    test();
    console.log(myList.length);
})

Upvotes: 3

Hrishi
Hrishi

Reputation: 1250

You are using the promise inside forEach, try this one:

res.items.forEach(async (itemRef, index) => {
    try {
        let metadata = await itemRef.getMetadata()
        if (metadata) {
            test();
        }
        else {
            console.log('error');
        }
    }
    catch (error) {
        console.log(error)
    }
});

Upvotes: 0

Related Questions