So I'm currently trying to figure out why this array is acting empty. I've tried finding the answer but so far I've had no luck. At the top I define var allMenuItems = []; and then in getMenuItems() I have multiple new class objects being pushed but when I call console.log(allMenuItems[0]); it comes back as undefined yet when I just call .log(allMenuItems) it comes back as being populated. Not 100% sure what I'm doing wrong here but I assume it's how I'm storing / reading the array any help is greatly appreciated.
the script is being imported using defer as a side note if that matters
var allMenuItems = [];
var imgRoot;
var price;
var time;
var menuItemTemplate = document.querySelector('#MenuItemTemplate');
var pizzaData = db.collection("MenuItems").doc("Pizzas");
var pizzaInfo = db.collection("MenuItems").doc("Pizzas").collection("Info");
var pizzaMenu = document.getElementById("PizzaMenu");
getMenuItems(pizzaInfo, pizzaMenu, pizzaData);
var wingsData = db.collection("MenuItems").doc("Wings");
var wingsInfo = db.collection("MenuItems").doc("Wings").collection("Info");
var wingsMenu = document.getElementById("WingsMenu");
getMenuItems(wingsInfo, wingsMenu, wingsData);
var sidesData = db.collection("MenuItems").doc("Sides");
var sidesInfo = db.collection("MenuItems").doc("Sides").collection("Info");
var sidesMenu = document.getElementById("SidesMenu");
getMenuItems(sidesInfo, sidesMenu, sidesData);
function getMenuItems(query, menuDiv, dataQuery) {
getItemData(dataQuery);
query.get().then((querySnapshot) => {
querySnapshot.forEach((doc) =>
{
var menuItemClone = menuItemTemplate.content.cloneNode(true);
menuItemClone.querySelector('#MenuItemImg').src = imgRoot doc.data().imgSrc;
menuItemClone.querySelector('#MenuItemName').innerText = doc.data().name;
menuItemClone.querySelector('#MenuItemDesc').innerText = doc.data().desc;
menuItemClone.querySelector('[class*="btn-danger"]').id = "MenuItem" doc.id;
menuDiv.appendChild(menuItemClone);
var newMenuItem = new MenuItem(doc.id, imgRoot doc.data().imgSrc, doc.data().name, doc.data().desc, price, time)
allMenuItems.push(newMenuItem);
});
});
}
function getItemData(query) {
query.get().then((doc) => {
if (doc.exists) {
imgRoot = doc.data().imgRoot;
price = doc.data().price;
time = doc.data().time;
} else {
console.log("No such document!");
}
}).catch((error) => {
console.log("Error getting document:", error);
});
}
function getMenuItemById(find)
{
console.log(find);
return allMenuItems.find(({ id }) => id === find);
}
class MenuItem
{
constructor(id, imgSrc, name, desc, price, time)
{
this.id = id;
this.imgSrc = imgSrc;
this.name = name;
this.desc = desc;
this.price = price;
this.time = time;
this.amount = 0;
}
}
console.log(allMenuItems[0]);
CodePudding user response:
The way you've written the code in the example, the last line (console.log(allMenuItems[0]);
) will execute before any of the promises in the getMenuItems
function get fulfilled. So I would expect the array to not be populated at that time.
To elaborate, the query.get()
call in getMenuItems
returns a promise. When you call then()
on that promise and pass a callback function that processes the results of the query and put them into allMenuItems
, that callback won't execute until the query completes - which could be a long time in the future. In the meantime, JavaScript will continue executing the rest of the synchronous code (including the console.log statement at the end).