reactjsexpressfetch-apiput

PUT 400 (bad request) HTTP Error Status 400


I am trying to update the quantity of my stocks using this function and it says PUT 400 (bad request). In my terminal for the back, i've inserted a console.log that confirms if the PUT request was received and it says that the request has been received. I've also tried using POSTMAN to check if the backend receives the PUT request

dashboard.jsx

const Dashboard = () => {
  const [productStocks, setProductStocks] = useState([]);

  const handleUpdateStock = (
    productID,
    productStock,
    quantityToAdd,
    quantityToRemove
  ) => {
    if (productStock !== undefined) {
      const body =
        quantityToAdd !== undefined ? { quantityToAdd } : { quantityToRemove };

      fetch(`http://localhost:8081/updateStock/${productID}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(body),
      })
        .then((response) => {
          if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
          }
          return response.json();
        })
        .then((data) => {
          console.log('Update response:', data);
          setProductStocks((prevProductStocks) => {
            const updatedProductIndex = prevProductStocks.findIndex(
              (product) => product.productID === productID
            );
            const updatedProductStocks = [...prevProductStocks];
            updatedProductStocks[updatedProductIndex] = {
              ...updatedProductStocks[updatedProductIndex],
              productStock: data.updatedStock,
            };
            return updatedProductStocks;
          });
        })
        .catch((error) => console.error('Error updating stock', error));
    } else {
      console.error('productID is undefined');
    }
  };
};

this is contains the return statement

return (
    <div className='div1'>
      <h1>Product Stocks</h1>
      <ul>
        {productStocks.map((product, index) => (
          <li key={index}>
            <strong>ID:</strong> {product.productID}, 
            <strong>Name:</strong> {product.productName}, 
            <strong>Stock:</strong> {product.productStock}
            <button onClick={() => handleUpdateStock(product.productID, product.productStock, 1)}>
              <MdAdd className="add-icon" /> /*am i passing the wrong arguments here? */
            </button>
            <button onClick={() => handleUpdateStock(product.productID, product.productStock, undefined, 1)}>
              <MdRemove className="remove-icon" />
            </button>
          </li>
        ))}
      </ul>
      </div>
    );
    };

This is my app.js

app.put('/updateStock/:productStock', (req, res) => {
    const { quantityToAdd, quantityToRemove } = req.body;
    const productStock = req.params.productStock;
  
    console.log('PUT request received:', req.body);
  
    if (isNaN(productStock) || isNaN(quantityToAdd) || isNaN(quantityToRemove) ||
      productStock < 0 || quantityToAdd < 0 || quantityToRemove < 0) {
      return res.status(400).json({ error: 'Invalid request. Parameters must be non-negative numbers.' });
    }
  
    const updateQuery = `
        UPDATE product 
        SET productStock = GREATEST(0, productStock ${quantityToAdd !== undefined ? '+' + quantityToAdd : '- ' + quantityToRemove})
        WHERE productStock = ?`;
  
    db.query(updateQuery, [productStock], (err, result) => {
      if (err) {
        console.error('Error updating stock:', err.message);
        return res.status(500).json({ error: 'Internal Server Error', details: err.message });
      }
      const selectQuery = 'SELECT productID, productName, productStock FROM product WHERE productStock = ?';
      db.query(selectQuery, [productStock], (err, updatedResult) => {
        if (err) {
          console.error('Error fetching updated stock:', err.message);
          return res.status(500).json({ error: 'Internal Server Error', details: err.message });
        }
        return res.json({ success: true, message: 'Stock quantity updated successfully.', updatedStock: updatedResult[0].productStock });
      });
    });
  });

I also think that there's an error in my app.js.

Can you help me solve the problem?

I've tried using just the productID to directly change the quantity of stocks however, it also says bad request. I expect the value of the productStock to increment/decrement.


Solution

  • const body =
      quantityToAdd !== undefined ? { quantityToAdd } : { quantityToRemove };
    

    Look at the body you're constructing for the request. It only has one of quantityToAdd or quantityToRemove yet your route handler checks both are positive numbers. With that check in place, it's always going to fail validation.

    You may want to alter the validation to something like this

    let validRequest = !(isNaN(productStock) || productStock < 0);
    if (quantityToAdd !== undefined) {
      validRequest &&= !(isNaN(quantityToAdd) || quantityToAdd < 0);
    } else if (quantityToRemove !== undefined) {
      validRequest &&= !(isNaN(quantityToRemove) || quantityToRemove < 0);
    } else {
      validRequest = false;
    }
    
    if (!validRequest) {
      return res
        .status(400)
        .json({
          error: "Invalid request. Parameters must be non-negative numbers.",
        });
    }