751 viewsMern Amazona
0 Comments

I would like to be able to reduce the stock size of a product after a purchase has been confirmed. I’m using the deliverOrderHandler as the trigger since an admin needs to manually press to confirm delivery.

I’ve created a function called reduceStockHandler that will remove one item from the countInStock size however, I am having issues updating the stock even by one. This is in the OrderScreen.js and I used ProductEdit.js as a template since that is a section that already updates the stock amount of a product.

Error:  Cannot read properties of undefined (reading ‘user’)

[apcode language=”jscript”]

const { id: productId } = useState('');
  const [user, setUser] = useState('');
  const [price, setPrice] = useState('');
  const [isPaid, setisPaid] = useState('');
  const [isDelivered, setisDelivered] = useState('');
  const [countInStock, setCountInStock] = useState('');
   useEffect(() => {
    const fetchData = async () => {
      try {
        dispatch({ type: 'FETCH_REQUEST' });
        order.orderItems?.map((item) => {
          const { data } = axios.get(`/api/products/${parseInt(item._id)}`);
          setUser(data.user);
          setPrice(data.totalPrice);
          setisPaid(data.isPaid);
          setisDelivered(data.isDelivered);
          setCountInStock(data.countInStock);
          dispatch({ type: 'FETCH_SUCCESS' });
        });
      } catch (err) {
        dispatch({
          type: 'FETCH_FAIL',
          payload: getError(err),
        });
      }
    };
    fetchData();
  }, [productId]);
   const reduceStockHandler = async (e) => {
    e.preventDefault();
     // Reduce stock of item by 1
    setCountInStock(setCountInStock - 1);
     try {
      dispatch({ type: 'UPDATE_REQUEST' });
      order.orderItems?.map((item) => {
        axios.put(
          `/api/products/${parseInt(item._id.id)}`,
          {
            _id: parseInt(item._id.id),
            user,
            price,
            isPaid,
            isDelivered,
            countInStock,
          },
          {
            headers: { Authorization: `Bearer ${userInfo.token}` },
          }
        );
      });
      dispatch({
        type: 'UPDATE_SUCCESS',
      });
      toast.success('Product updated successfully');
    } catch (err) {
      toast.error(getError(err));
      dispatch({ type: 'UPDATE_FAIL' });
    }
  };

[/apcode]

Thank you for your time,

Khalid

Bassir Changed status to publish November 26, 2023

hello there,

fist of all don’t use this code:
<code>[apcode language="jscript"]

order.orderItems?.map((item) => {
        axios.put(
          `/api/products/${parseInt(item._id.id)}`,
          {
            _id: parseInt(item._id.id),
            user,
            price,
            isPaid,
            isDelivered,
            countInStock,
          },
          {
            headers: { Authorization: `Bearer ${userInfo.token}` },
          }
        );
      });

[/apcode]
because axios.put is an async function and show be used by await.
second: update countInStock in backend like this:

This is a new feature called inventory management.

It’s been noted for future updates.

the idea is to find all products in the orderItems and decrease them in a for loop in order create api.

[apcode language="jscript"]

for (const index in order.orderItems) {
const item = order.orderItems[index];
const product = await Product.findById(item.product);
product.countInStock -= item.qty;
await product.save();
 }

[/apcode]

Bassir Answered question October 11, 2022