0

I would really appreciate if anyone could help me with this.

Objective : If the item added by clicking "+" :

  1. It needs to check if the order already exists (if yes, then increment the quantity)
  2. If not then append that item to the orders list

fullmenu contains the list of all items in the following schema :

{  _id: 5eef61450bd95e1f5c8f372f ,
  name: "Burger"   ,
  category: "American"  ,
  price: "100"  ,
  isVeg: false,
  qty: 0
}

ISSUE : It adds a new object of item even if it already exists in the orders array instead of just incrementing it's quantity

The main code logic :

    const [total, setTotal] = useState(0);
    const [orders, setOrders] = useState([]);
    const [fullMenu, setFullMenu] = useState();
    const addMore = (e) => {
        let sign = e.target.innerText;
        let id = e.target.id;
        const newOrders = [...orders];
        let order = newOrders.find(each => each.id === id);
        // if the order already exists for the item
        if (order) {
            let _sign = sign === "+" ? 1 : -1;
            // increase or decrease the quantity
            order.qty = (order.qty || 0) + 1 * _sign;
            // remove item from order list if qty = 0
            if(!order.qty){
                setOrders(orders => orders.filter(each => each.id !== id));
                // setTotal(total => total - parseInt(order.price));
                return;
            };
            // save 
            setOrders(newOrders);
            if (sign === "+") setTotal(total => total + parseInt(order.price));
            if (sign === "-") setTotal(total => total - parseInt(order.price));
            return;
        };
        // if item doesn't exist in the order list
        const item = fullMenu.find(each => each._id === id);
        if (sign === "+") {
            order = {
                ...item, qty: 1 
             };
            setOrders(orders => [...orders, order]);
            setTotal(total => total + parseInt(order.price));
        };
    }

JSX :

<div className="col-sm-4"><span id={each._id} onClick={addMore} category={each.category}>-</span></div>
<div className="col-sm-4"><FormCheckLabel className="qty" >{each.qty}</FormCheckLabel></div>
<div className="col-sm-4"><span id={each._id} onClick={addMore} category={each.category}>+</span></div>
3
  • what exactly the error in your code? what is the desired behavior that not happening? Commented Jun 22, 2020 at 13:26
  • mentioned the issue above Commented Jun 22, 2020 at 13:27
  • 1
    just updated the answer pls chk.... also upvoted ur qn as it was clear about the issue description (not sure why there was a downvote) Commented Jun 22, 2020 at 13:52

3 Answers 3

1

You need to find the order using each._id not each.id

...
let order = newOrders.find(each => each._id === id);
...

Edit: Another thing noticed was that you were mutating the state directly

Refactored code

const addMore = (e) => {
  let sign = e.target.innerText;
  let id = e.target.id;
  const newOrders = [...orders];
  let orderIndex = newOrders.findIndex((each) => each._id === id); //<---use correct ._id
  if (orderIndex !== -1) {
    let _sign = sign === "+" ? 1 : -1;
    // order.qty = (order.qty || 0) + 1 * _sign; //<----don't mutate like this
    const updatedOrder = {...newOrders[orderIndex]};
    updatedOrder.qty = (updatedOrder.qty || 0) + 1 * _sign;; //<---update state like this

    if (!updatedOrder.qty) {
      setOrders((orders) => orders.filter((each) => each._id !== id)); //<---use correct ._id
      return;
    }
    // save
    newOrders[orderIndex] = updatedOrder;//<----save updated order like this
    setOrders(newOrders);
    if (sign === "+") setTotal((total) => total + parseInt(order.price));
    if (sign === "-") setTotal((total) => total - parseInt(order.price));
    return;
  }
  const item = fullMenu.find((each) => each._id === id);
  if (sign === "+") {
    order = {
      ...item,
      qty: 1,
    };
    setOrders((orders) => [...orders, order]);
    setTotal((total) => total + parseInt(order.price));
  }
};

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

1 Comment

Thanks alot. This worked for me, I'll post the final answer too.
0
  • let order = newOrders.find(each => each.id === id); should be each._id
  • You forgot else:

const [total, setTotal] = useState(0);
    const [orders, setOrders] = useState([]);
    const [fullMenu, setFullMenu] = useState();
    const addMore = (e) => {
        let sign = e.target.innerText;
        let id = e.target.id;
        const newOrders = [...orders];
        let order = newOrders.find(each => each.id === id);
        // if the order already exists for the item
        if (order) {
            let _sign = sign === "+" ? 1 : -1;
            // increase or decrease the quantity
            order.qty = (order.qty || 0) + 1 * _sign;
            // remove item from order list if qty = 0
            if(!order.qty){
                setOrders(orders => orders.filter(each => each.id !== id));
                // setTotal(total => total - parseInt(order.price));
                return;
            };
            // save 
            setOrders(newOrders);
            if (sign === "+") setTotal(total => total + parseInt(order.price));
            if (sign === "-") setTotal(total => total - parseInt(order.price));
            return;
        }else{
          // Should be in else block like this
          // if item doesn't exist in the order list
          const item = fullMenu.find(each => each._id === id);
          if (sign === "+") {
            order = {
                ...item, qty: 1 
             };
            setOrders(orders => [...orders, order]);
            setTotal(total => total + parseInt(order.price));
          };
        }
    }

Comments

0

This finally worked, thanks to @gdh. Made on small tweak:

const [total, setTotal] = useState(0);
    const [orders, setOrders] = useState([]);
    const [fullMenu, setFullMenu] = useState();
    const addMore = (e) => {
        let sign = e.target.innerText;
        let id = e.target.id;
        const newOrders = [...orders];
        let orderIndex = newOrders.findIndex(each => each._id === id);
        // if the order already exists for the item
        if (orderIndex !== -1) {
            let _sign = sign === "+" ? 1 : -1;
            // increase or decrease the quantity
            const updatedOrder = {...newOrders[orderIndex]};
            updatedOrder.qty = (updatedOrder.qty || 0) + 1 * _sign;
            // remove item from order list if qty = 0
            if(!updatedOrder.qty){
                setOrders(orders => orders.filter(each => each._id !== id));
                setTotal(total => total - parseInt(updatedOrder.price));
                return;
            };
            // save 
            newOrders[orderIndex] = updatedOrder;
            setOrders(newOrders);
            if (sign === "+") setTotal(total => total + parseInt(updatedOrder.price));
            if (sign === "-") setTotal(total => total - parseInt(updatedOrder.price));
            return;
        };
        // if item doesn't exist in the order list
        const item = fullMenu.find(each => each._id === id);
        if (sign === "+") {
            let order = {
                ...item, qty: 1 
             };
            setOrders(orders => [...orders, order]);
            setTotal(total => total + parseInt(order.price));
        };
    }

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.