Home > Software design >  JavaScript Array of class objects acts empty when it shouldn't be
JavaScript Array of class objects acts empty when it shouldn't be

Time:04-13

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).

  • Related