0

I have an html file with a form for a person to fill out to take an order.

I have a global array to store objects. The objects contain the name, price, and quantity of the item added to the order.

<button type="button" onclick="addToOrder('app2-amount', 'House Salad', '6')">+</button> 

This is where addToOrder() is called.

And the function:

var orderArray = [];

function addToOrder(id, nameIn, priceIn){
if (loggedIn == true){
  var quantityIn = document.getElementById(id).value;
  var totalForThisItem = priceIn*quantityIn;

  var menuObject = {
     name: nameIn,
     price: totalForThisItem,
     quantity: quantityIn
   };

   // Next we must perform a check to see if an object with the same name already exists in the order
   // If it does exist, replace it with this new object.
   if (orderArray.length == 0){
     orderArray.push(menuObject);
   }
   else{
     orderArray.forEach( function (item) {
       if (item.name == menuObject.name){
         item = menuObject;
       }
       else{
         orderArray.push(menuObject);
       }
     });
   }
   console.log("dabs " + orderArray.toString());
   }
    // If user is not logged in:
   else{
   console.log("You are not logged in. Please log in to use this feature.");
    }
 console.log(menuObject);
}

When I print menuObject, I thought it would be out of scope, deleted. I am inserting it into a global variable, and I think it is screwing me over.

Some odd things happen when I starting putting different menu items into the array. In one case, it added 3, 6, 12, 24, etc. with each press. Kinda funny, but I'm pretty bummed.

What happens here?

4
  • When I print menuObject, I thought it would be out of scope, deleted Its because you are printing it within the function(at the end), its not yet out of scope. Other than that your question is not clear what exactly is your issue? put some example/scenarios with data to explain. Commented Apr 22, 2016 at 2:29
  • The odd behavior when I added different menu items to the list. I am also so used to coding in Java, I didn't realize that it is not out of scope of the function (thinking that last bracket is a class ending). It is however out of scope of the If. Does that mean anything? Commented Apr 22, 2016 at 2:30
  • Try changing item = menuObject; to item.name = menuObject.name; item.price = menuObject.price; item.quantity = menuObject.quantity or rather insert directly into array Commented Apr 22, 2016 at 2:36
  • Inserting directly to the array as {name: nameIn, price: totalForThisItem, quantity: quantityIn} is still adding multiple objects with a single click. Commented Apr 22, 2016 at 2:40

1 Answer 1

3

You've slightly misunderstood lexical scoping in Javascript, I think.

var declarations are scoped at the function block level. That means that even though your var statement is inside of an if block, it has scope throughout the entire function, and remains defined until the function exits. They're also valid everywhere in the function (even before their declaration), due to hoisting.

If you're writing in ES6, you can also use let declarations, which are scoped to the nearest enclosing block...in your case, the if block. That'd be the behavior I think you were expecting here.

Your other issue is logical. With each pass through your function, you're using forEach to traverse your array, and then potentially pushing your new object once for every existing object in the array. That's why you're getting a geometric progression in your array length.

If your intent was 'replace the matching item in the array if it's already there, otherwise add it to the end' then there are a couple ways you can do that. Array.find is one option, but there are several approaches that'd work.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. I'm thinking I don't need it at all, and can just directly use: {name: nameIn, price: totalForThisItem, quantity: quantityIn} Where I use menuObject.
I'd overlooked your other question...edited to add further answer!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.