When working with a JavaScript array of class objects, it may appear as though the array is empty when it

Currently puzzled by the behavior of this array. Despite my efforts to find an answer, I haven't had any luck so far. I initialize var allMenuItems = []; at the top and then in getMenuItems(), I push multiple new class objects. However, when I call console.log(allMenuItems[0]); it returns as undefined. Yet when I simply call .log(allMenuItems), it shows that the array is populated. Not entirely sure where I'm going wrong, but I suspect it's related to how I'm storing/reading the array. Any help would be greatly appreciated.

Note: The script is being imported using defer

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]);

Answer №1

The code example is structured in a way that causes the last line (console.log(allMenuItems[0]);) to run before any of the promises in the getMenuItems function are fulfilled. This means that the array may not be populated by that point.

In essence, the query.get() call within the getMenuItems function returns a promise. When you use then() on this promise and provide a callback function to handle the query results and populate the allMenuItems array, the callback will only execute once the query has completed - which could potentially take a while. Meanwhile, JavaScript continues to run the synchronous code, including the console.log statement at the end.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

My preference is for the most straightforward ajax form application available

I'm looking to create an ajax application that can handle a basic form with just text input and a submit button. I don't need any validation included, just a simple PHP script to process the form data. I'm reaching out for help because I hav ...

What might be preventing combineLatest from executing?

Currently, I am attempting to run a block of code utilizing the combineLatest function. Within my translation library, there exists an RXJS Observable that is returned. Imported as individual functions are combineLatest, map, and tap. combineLatest(this. ...

Google Maps integrated AWS server

While utilizing an AWS server for my application, I have encountered a difficulty with Google Maps. When running my application using localhost, Google Maps functions perfectly fine. However, when attempting to run the application using an IP address, it f ...

The passport authentication process is malfunctioning as there seems to be an issue with the _verify function

Having an issue and could use some assistance. I am currently implementing passport in my express application. While I am able to successfully register a user, I encounter an error when trying to log in. TypeError: this._verify is not a function at Str ...

Can a hyperlink exist without a specified href attribute?

One scenario could be when I receive this specific code from a third-party source <a class="cs_import">Add contacts from your Address Book</a> Curiously, the link "Add contacts from your Address Book" does not redirect to any page as expected ...

WebRTC error encountered: Unable to add ICE candidate to 'RTCPeerConnection'

Encountering a specific error in the browser console while working on a project involving p2p video chat. The error message is Error: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': The ICE candidate could not be added.. Int ...

"Adjusting Material UI Select Size - A Guide to Resizing Your

Struggling with getting Material UI selects to work properly with height and width using 'vh' and 'vw', as well as adjusting text size with 'vh'. The boxes have the correct size, but the label text is no longer centered due t ...

The functionality of $(selector).css() seems to be malfunctioning

I currently have an html div element stored in a variable var rows = ""; rows += "<div>1111 : Hi there</div>"; Despite multiple attempts, I have failed to add a background color to this div using the following methods: 1. $(rows).css({&apos ...

The function d3.json() does not support googleoverlay

As a newcomer to coding, I am currently working on incorporating the code found at https://bl.ocks.org/mbostock/899711. Instead of using a local .json file, I have opted to read JSON data from a URL. However, I encountered an issue where the LAT and LONG v ...

Discovering the specific object ID that triggered an event in JavaScript

I am developing a webpage that includes JavaScript functionality. There is a specific function in the Javascript code which gets triggered by two different elements when clicked: 1. When a checkbox is clicked: $('#chkShowAll').click( functi ...

Switching up the content of an HTML page with JavaScript or JQuery: what you need

Is it possible to update HTML content using JavaScript or JQuery? https://i.sstatic.net/EWOXg.png I am trying to change the contents from 1 to 5 in a sequential order based on the time shown in the image. How can I achieve this using JavaScript or JQuery ...

Steps to transfer the content of a label when the onclick event occurs

Seeking advice on how to send the dynamically varying value of a label upon clicking an anchor tag. Can anyone recommend the best approach to passing the label value to a JavaScript function when the anchor is clicked? Here is a sample code snippet: < ...

Using the Ternary Operator in JavaScript to Dynamically Update HTML Elements with Angular

Is there a way to convert the code below into a ternary operator so that it can be used in an .HTML file? statusChange && statusChange === 'Employed' ? true : employmentStatus === 'Employed'; To clarify, I want to assign the re ...

In a jQuery application, the action of adding text from an input field to a div is triggered by clicking a

It's possible this is a duplicate question, but none of the answers I found solved my issue. I'm attempting to create a jQuery script where text entered into a text box is appended to a div when a button is clicked. This is part of a game I' ...

Why does my express POST request result in an empty req.body in Node.js?

After confirming that my data is being passed correctly and the db connection is successful, I am facing an issue with my ajax request. Even though the success callback returns the id, my data seems to not be passing through properly. When attempting to a ...

how to change class on vue function result

I need a way to display the content stored in requestData as li elements. Each list item should have an onclick function that, when clicked (selected), adds a specific value from a reference to an array. If clicked again (unselected), it should remove the ...

Obtain the final value within a URL's path segment

If we have an href similar to: http://localhost:8888/#!/path/somevalue/needthis Is there a way to extract the last value in the path string (i.e., "needthis")? I experimented with window.location.pathname, but it only returns "/". Another attempt was m ...

Having trouble with table sorting in Jquery?

I am a beginner in the realm of Jquery and web programming. Recently, I attempted to implement the tablesorter jquery plugin for one of my projects but encountered issues with making it work properly. In search of a solution, I turned to Stack Overflow. C ...

What is the method of using "*" as the value for allowedModules in a jsreport configuration file to enable all modules?

I am having an issue when trying to generate a report using jsreport STUDIO. The error message I received is as follows: An error occurred - Error during rendering report: Unsupported module in scripts: request. To enable require on a particular module, ...

Querying MongoDB for pulling/updating nested arrays in a paginated manner

In my database, I have a series of documents structured like this: Document1: { name: "tester1", reports: [{ name: "report1", type: "overflow" }, { name: "repor ...