1
export default function ShoppingCart() {
  const classes = useStyle();
  const {
    productsList, filteredProductsList, setFilteredProductsList, setProductsList,
  } = useContext(productsContext);
  const [awaitingPaymentList, setAwaitingPaymentList] = useState([]);
  const [addedToCartList, setAddedToCartList] = useState([]);
 

  const addToCartHandler = useCallback((itemId) => {
    const awaitingPaymentListIds = awaitingPaymentList.map((item) => item.id);
    const isInAwaitingPaymentList = awaitingPaymentListIds.includes(itemId);

    isInAwaitingPaymentList ? setAddedToCartList([...addedToCartList, addedToCartList.push(awaitingPaymentList[awaitingPaymentList.findIndex((item) => item.id === itemId)])]) : setAddedToCartList([...addedToCartList]);

    isInAwaitingPaymentList
      ? setAwaitingPaymentList(awaitingPaymentList.splice(awaitingPaymentList.findIndex((item) => item.id === itemId), 1))
      : setAwaitingPaymentList([...awaitingPaymentList ])

    setProductsList(awaitingPaymentList);
  }, [addedToCartList, awaitingPaymentList, setProductsList]);

  useEffect(() => {
    setFilteredProductsList(
      productsList.filter((product) => product.status === 'AWAITING_PAYMENT'),
    );
  }, [productsList, setFilteredProductsList, setFilteredProductsList.length]);

  useEffect(() => {
    setAwaitingPaymentList(filteredProductsList);
  }, [filteredProductsList]);

I manage to delete the item from awaitingPaymentList and to add it into addedToCartList but looks like I am doing something wrong because it is adding the object, but the previous ones are replaced with numbers :). On the first click, the array is with one object inside with all data, but after each followed click is something like this => [1,2,3, {}]. When I console log addedToCartList outside addToCartHandler function it is showing an array: [1] :)))

Since there is some code I hope I am not going to receive a lot of negative comments like last time. And if it's possible, to give me a clue how to make it for all items to be transferred at once, because there will be a button to add all. Thank you for your time.

1
  • Can you provide a working CodePen or similar? Commented Nov 6, 2020 at 9:36

1 Answer 1

1

I think this line of code is causing issue:

isInAwaitingPaymentList
  ? setAddedToCartList([
      ...addedToCartList,
      addedToCartList.push(
        awaitingPaymentList[
          awaitingPaymentList.findIndex((item) => item.id === itemId)
        ]
      )
    ])
  : setAddedToCartList([...addedToCartList]);

array.prototype.push returns the new length of the array that you are pushing into, this is likely where the incrementing element values are coming from. The push is also a state mutation.

It is not really clear what you want this code to do, but I think the push is unnecessary. Perhaps you meant to just append the last element into the new array you are building.

isInAwaitingPaymentList
  ? setAddedToCartList([
      ...addedToCartList, // <-- copy state
      awaitingPaymentList[ // <-- add new element at end
        awaitingPaymentList.findIndex((item) => item.id === itemId)
      ]
    ])
  : setAddedToCartList([...addedToCartList]);

Suggestion

If you simply want to move an element from one array to another then find it in the first, then filter it from the first, and copy to the second if it was found & filtered.

const itemToMove = awaitingPaymentList.find(item => item.id === itemId);
setAwaitingPaymentList(list => list.filter(item => item.id !== itemId));
itemToMove && setAddedToCartList(list => [...list, { ...itemToMove }])
Sign up to request clarification or add additional context in comments.

20 Comments

Yeap thank you very much I was wondering couple of hours, what I am doing wrong here. :)
@DragoJokera The filter function removes the element from the first array. Can you provide a running code sandbox for this component? I don't think you need to wire up the context provider, but if you could mock the local component state and render this component I can take a look at how data is flowing through it. Perhaps you've more state mutation/update issues elsewhere. Here is my codesandbox test
@DragoJokera Are you trying to console log the state right after the update in the addToCartHandler function? This will only log the current state, not the enqueued state for the next render cycle. Try logging state in its own useEffect hook with appropriate dependency. I added logging to my linked sandbox.
@DragoJokera Ok, so instead of completely overwriting addedToCartList with the contents of awaitingPaymentList you need shallow copy the current contents of addedToCartList first, then shallow copy the contents of awaitingPaymentList. I.e something like const addAllToCart = () => { setAddedToCartList(cart => [...cart, ...awaitingPaymentList]); setAwaitingPaymentList([]); };.
Yeap, that is working fine, I tried it but I just made a shallow copy of the current content of addedToCartList and the awaitingPaymentList without making a shallow copy of it. addAllToCart = () => { setAddedToCartList(cart => [...cart, awaitingPaymentList]). Thanks once again.
|

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.