I know there are tons of questions and answers on using Javascript promises to load returned Firebase objects, but I haven't succeeded in capturing the data in an array.
The issue: I've set up an array (productArray below) to iteratively take in values of a Firebase snapshot, but the array remains empty after exiting the forEach loop.
database.js:
getProductList = function(){
let productArray =[];
loadFBData = function(){
firebase.initializeApp(config);
return firebase.database().ref().once("value", function(snapshot){
return snapshot.val();
});
}
Promise.all([loadFBData()]).then(function(snapshot) {
snapshot.forEach(function(product) {
productArray.push(product.val());
});
});
}
Question: I think I'm using Promise.all wrong, but can't figure out how (also am new asynchronous functions). Thanks for any hints on how to get productArray to successfully load.
Edit: To elaborate, it seems snapshot is loading with the correct Firebase data, and the forEach is correctly looping through each item in snapshot but productArray becomes (or remains) empty outside of the Promise.all statement.
Update I implemented all the suggestions below and yet, the program will not stop long enough to build an array from the snapshot object. Last year I used Angularfire's $loaded function which was so effective in getting the program to wait so I don't understand why an ordinary JS promise won't work here. Does it make sense to resort to timeout? I even tried to combine alexmac's and Pointy's suggestions, but no cigar:
getProductList = function(){
let productArray =[];
loadFBData = function(){
firebase.initializeApp(config);
return new Promise(resolve => {
firebase.database().ref().once('value')
.then(function(snapshot){
return resolve(function(snapshot){
productArray = Object.keys(snapshot).map((key, prod) => prod);
});
});
});
}
loadFBData();
}
snapshotis indeed loading with Firebase data. The issue is (or must be) in thatforEachloop, since (right afterPromise.alland inside ofgetProductList()),productArray.lengthreturns 0.loadFBData()function needs to return a new Promise with the current code inside the Promise callback. The function should pass the data retrieved to theresolve()function.Promise.allonly for one element? Also iffirebase.database().ref().oncereturns a promise, you don't needPromise.allat all.