Need help with the Javascript output

I am working on an app that does the follow:

  1. User add fruits and quantity
  2. function take entries and tell if quantity is low or okay.
  3. Add displays results in the web page

Error msg
"can not read properties of undefines ( reading ‘entries’)

const fruits = [];


function addFruits() {
  let name = document.getElementById("fruit-name").value;
  let quantity = Number(document.getElementById("fruit-quantity").value);

  
  fruits.push({ name: name, quantity: quantity });
    
  console.log(fruits);




  // Callback function to select low volumes 
function myCallback({ quantity }) {
  return quantity > 200 ? "ok" : "low";
}

  // Group by ok and low
const result = Object.groupBy(fruits, myCallback);


 // Display Results
let test ="These fruits are Ok: <br>";
for (let [name,quantity] of result.ok.entries()) {
  test += name.name + " " + quantity.quantity + "<br>";
}

  test += "These fruits are low: <br>";
for (let [name,quantity] of result.low.entries()) {
  test += name.name + " " + quantity.quantity + "<br>";
}
  document.getElementById("low-inventory-content").innerHTML = test;
   document.getElementById("high-inventory-content").innerHTML = okInventory ;

 
};

 <div class="container">
    <div class="form-col">
      <div class="form-group">
        <input type="text" id="fruit-name" placeholder="Enter Fruit Name" class="form-control">
        <p id="name-alert"></p>
        <input type="number" id="fruit-quantity" placeholder="Enter Quantity" class="form-control">
        <p id="age-alert"></p>

        <button id="add-fruit" onClick="addFruits()">Add Fruit</button>
      </div>

    </div>

    <div class="low-inventory-col">
      <p id="low-inventory-content"></p>
    </div>
    <div class="high-inventory-col">
       <p id="high-inventory-content"></p>
    </div>
  </div>

Hi there!

The method Object.groupBy is not a standard JavaScript method. It is likely from a proposal or a library that you haven’t imported. To implement grouping, you need to write a custom grouping function or use libraries like Lodash.

In the loop You are destructuring name and quantity, but this is incorrect because the items in result.ok (and result.low) are not iterable objects or maps. You likely need to loop directly through the array of objects (e.g., for (let fruit of result.ok)).

You use document.getElementById(“low-inventory-content”).innerHTML = test;, but there’s no okInventory variable for high inventory content. The variable should be defined, or you need to update the logic to include the results for “ok” fruits.

To fix your code, replace Object.groupBy with a custom groupBy function using Array.reduce() since Object.groupBy is not a standard method in JavaScript.
Loop through the grouped arrays directly instead of using destructuring like entries(), as result.ok and result.low are arrays, not maps. Ensure to check if the ok and low groups exist before looping to prevent runtime errors. Use appropriate variables for the results, such as test, to hold concatenated strings for display. Update the DOM with the correct content for both “low inventory” and “high inventory” sections. Verify the HTML structure includes the required input fields (fruit-name and fruit-quantity) and containers (low-inventory-content and high-inventory-content) to avoid null references. Add a console.log statement to debug the fruits array after each addition.

I was trying to remix this from w3schools and it seems like used some libraries and didn’t mentioned it in the tutorial. thanks for the feedback. I am going to practice some lower level coding first before taking on this project again.


1 Like

groupBy should be supported.


The array has to have objects that have both low and ok quantities before running the code that does the groupBy. The code from the demo works because it has both.

Also, as said, you have misinterpreted what x and y is in the for...of loop code. Notice how they only use y.

I will say I find their code confusing to read. If you drop the .entries() you can just use the objects.

for (let fruit of result.ok) {
  text += fruit.name + " " + fruit.quantity + "<br>";
}

Or use destructuring with the objects

for (let { name, quantity } of result.ok) {
  text += name + " " + quantity + "<br>";
}