0

First time working with a shopping cart component, I have my code structured like this..

let cartCount = document.getElementById("counter");
let isItemSelected = false;
let itemCount = 0;
let shoppingCart = [];
let selectedSize = "";
let displaySelectedSize = document.getElementById("selected");
let displayCart = document.getElementById("cart");



selectItem = () => {  
  isItemSelected = true;
  selectedSize = event.srcElement.id;
  displaySelectedSize.innerHTML = `${selectedSize}`;
}

addItem = () => {
  if (isItemSelected === true) {

    const shopItem = {
      name: "Classic Tee",
      price: 75,
      size: `${selectedSize}`,
      quantity: 0
    }

    itemCount+= 1;
    cartCount.innerHTML = `( ${itemCount} )`;    
    shopItem.quantity++
    shoppingCart.push(shopItem);
    console.log(shoppingCart);

    return itemSuccess();
  } else {
      return itemError();
  }
}

What I basically need is for the shopItem.quantity to increase if I have multiple of the selected size.

At the moment I get this..

// Output
0: {name: "Classic Tee", price: 75, size: "small", quantity: 1}
1: {name: "Classic Tee", price: 75, size: "small", quantity: 1}

// Desired Output
0: {name: "Classic Tee", price: 75, size: "small", quantity: 2}

I can see why my output is like that, it's creating a new object each time my addItem function is fired, but I would like to mutate my shopItem.quantity if there are duplicates...

How would I do that?

invrt
  • 689
  • 6
  • 24
  • Search for existing objects with the same attributes (https://stackoverflow.com/q/13964155/215552) and update the quantity. – Heretic Monkey May 27 '19 at 00:52
  • Possible duplicate of [Get JavaScript object from array of objects by value of property](https://stackoverflow.com/questions/13964155/get-javascript-object-from-array-of-objects-by-value-of-property) – Heretic Monkey May 27 '19 at 01:14

3 Answers3

3

You can give item time an identity attribute (I would not go by name, since it is possible you can have something with the same name and that would be bad) such as id and the you can search for it before adding something. For example, consider the following item:

const cartItem = {id: 1, name: "Classic Tee"}

Then before adding the item, you could look for it in the cart:

const existingItem = shoppingCart.find((item) => {
  return cartItem.id === item.id;
});

if(existingItem) {
   existingItem.quantity++;
} else {
  // Push the item into the cart
  shoppingCart.push(cartItem);
}
Vaughan Hilts
  • 2,839
  • 1
  • 20
  • 39
  • I get this error: 'Uncaught ReferenceError: Cannot access 'existingItem' before initialization' when trying to trigger function more than once – invrt May 27 '19 at 03:43
  • You would be putting this code inside of `addItem` If you do this, you shouldn't have an issue AFAIK – Vaughan Hilts May 27 '19 at 03:45
  • My answer had a mistake. I forked it here: https://codepen.io/anon/pen/YbvXeQ It should work. – Vaughan Hilts May 27 '19 at 03:58
1

I think you should filter your shoppingCart array and depending on it if you should add a new item to the array or increment the quantity of an existing item.

Here's a sample based on what you started. I removed some code so I can focus on the gist of what I mean

let shoppingCart = [];


addItem = (newItem) => {

    function itemFilter(item) {
        return item.name === newItem.name && item.price === newItem.price && item.size === newItem.size
    }
    let existingItems = shoppingCart.filter(itemFilter)

    if (existingItems.length > 0) {
        existingItems[0].quantity += newItem.quantity
    } else {
        shoppingCart.push(newItem)
    }

}

const shopItem = {
    name: "Classic Tee",
    price: 75,
    size: "small",
    quantity: 1
}

const shopItem2 = {
    name: "Classic Tee",
    price: 75,
    size: "big",
    quantity: 1
}

const shopItem3 = {
    name: "Classic Tee",
    price: 75,
    size: "small",
    quantity: 2
}

console.log('-----------')
console.log(shoppingCart)
addItem(shopItem)
console.log('-----------')
console.log(shoppingCart)
addItem(shopItem)
console.log('-----------')
console.log(shoppingCart)
addItem(shopItem2)
console.log('-----------')
console.log(shoppingCart)
addItem(shopItem)
console.log('-----------')
console.log(shoppingCart)

output is:

-----------
[]
-----------
[ { name: 'Classic Tee', price: 75, size: 'small', quantity: 1 } ]
-----------
[ { name: 'Classic Tee', price: 75, size: 'small', quantity: 2 } ]
-----------
[ { name: 'Classic Tee', price: 75, size: 'small', quantity: 2 },
  { name: 'Classic Tee', price: 75, size: 'big', quantity: 1 } ]
-----------
[ { name: 'Classic Tee', price: 75, size: 'small', quantity: 4 },
  { name: 'Classic Tee', price: 75, size: 'big', quantity: 1 } ]
Aaron
  • 147
  • 2
0

You can also use reduce like this:

    const fakeGiftCardList2 = [
        { value: 8, quantity: 1, cost: 3 },
        { value: 8, quantity: 1, cost: 3 },
        { value: 8, quantity: 1, cost: 3 },
        { value: 8, quantity: 1, cost: 3 },
        { value: 8, quantity: 1, cost: 3 },
        { value: 10, quantity: 1, cost: 12 },
    ];
    const red = (obj, item) => {
        obj[item.value]
            ? (obj[item.value].quantity += 1)
            : (obj[item.value] = { ...item });
        return obj;
    };

    const arrayHashmap = fakeGiftCardList2.reduce(red, {});
    const mergedArray = Object.values(arrayHashmap);
    console.log(mergedArray);