0

I'm building a simple shopping cart for a site and have been working on the add to cartaction. While I have ti working I feel there is probably a simple more elegant way of doing it.

This is the starting state:

start_state = {
  inventory: [
   {sku: "product_1", price: 600, name: "Product 1"},
   {sku: "product_2", price: 800, name: "Product 2"}
  ],
  cart: []
}

And this is the desired end state:

start_state = {
  inventory: [
   {sku: "product_1", price: 600, name: "Product 1"},
   {sku: "product_2", price: 800, name: "Product 2"}
  ],
  cart: [
   {sku: "product_1", quantity: 2},
   {sku: "product_2", quantity: 1}
  ]
}

And this is the function Im triggering to take it from the initial state to new final_state, the sku argument is the item from the state that is passed in when the action is called:

addToCart: function (sku) {
  let currentCart = this.state.cart
  let itemInCart = _.findIndex(currentCart, ['sku', sku])

  let newItem = { sku: sku }
  if (itemInCart !== -1) {
    let newQuantity = currentCart[itemInCart].quantity
    newItem.quantity = newQuantity + 1
  } else {
    newItem.quantity = 1
  }

  let filteredCart = _.filter(currentCart, (item) => { return item.sku !== sku })
  let newCart = _.concat(filteredCart, newItem)

  this.setState({cart: newCart})
},
2
  • are you using es6? Commented Jun 20, 2016 at 10:21
  • Yes using Babel to transpile Commented Jun 20, 2016 at 10:23

2 Answers 2

1

Since you are using ES6, you can use some of its new features like findIndex and Object.assign to achieve what you want.

addToCart: function(product) {
        let index = this.state.cart.findIndex((x) => x.sku === product.sku);
        if(index === -1) {
          let newProduct = {sku: product.sku, quantity:1}
            this.setState({cart : this.state.cart.concat([newProduct])})
        }
        else {
          let newCart = Object.assign([], this.state.cart);
          newCart[index].quantity = newCart[index].quantity+1;
          this.setState({cart: newCart});
        }
}

full working example

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

Comments

0

I think this way is better:

function getCardWithIncItem(currentCart, itemInCart) {
    return [
        ...currentCart.slice(0, itemInCart),
        Object.assign({}, currentCart[itemInCart], {
            quantity: currentCart[itemInCart].quantity + 1,
        }),
        ...currentCart.slice(itemInCart + 1),
    ];
}

function getCardWithNewItem(currentCart, sku) {
    return [
        ...currentCart, {
            sku: sku,
            quantity: 1,
        }
    ];
}

const currentCart = this.state.cart;
const itemInCart = _.findIndex(currentCart, ['sku', sku]);
const newCart = (itemInCart !== -1)
    ? getCardWithIncItem(currentCart, itemInCart)
    : getCardWithIncItem(currentCart, sku);
this.setState({
    cart: newCart,
})

Comments

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.