skip to Main Content

I have a product list(without quantity) in json-server and fetch using react-redux and rendered in table. I also have a input field to get quantity from user to calculate the total by mutiplying product price(from json-server) with product quantity(from input field).

The total field in list showing NaN. I guess the problem is with qty. How to avoid the error? how to initialise initial state to 0 for all input field in table?

import FormInput from './Components/FormInput';
import { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { fetchList } from './Components/Store/action';
function App() {

  const { list } = useSelector((state) => state.list)
  const dispatch = useDispatch()
  const [qty, setQty] = useState({})
 
  const handleChange = (e) => {
    e.preventDefault()
    const { name, value } = e.target;
    setQty({
      ...qty,
      [name]:value 
    });
  }


  useEffect(() => {
    dispatch(fetchList())
  }, [dispatch])


  let sum = 0

  list.forEach((item) => {
    sum += item.price * qty[item.name]
  })


  const submitHandler = (e) => {
    e.preventDefault()
  }

  return (
    <div >
      <form onSubmit={submitHandler}>
        <table>
          <thead>
            <tr>
              <th>S.no</th>
              <th>Name</th>
              <th>Unit</th>
              <th>price</th>
              <th>Quantity</th>
              <th>total</th>
            </tr>
          </thead>
          <tbody>
            {list.map((item) => (
              <tr key={item.id}>
                <td>{item.id}</td>
                <td>{item.name}</td>
                <td>{item.unit}</td>
                <td>{item.price}</td>
                <td>
                  <FormInput
                    type="number"
                    name={item.name}
                    handleChange={handleChange}
                    value={qty[item.name]} 
                  />
                </td>
                <td>{item.price * qty[item.name]}</td>
              </tr>
            ))}
          </tbody>
        </table>
        <button type='submit'>Submit</button>
      </form>
      <h1>total:{sum}</h1>
    </div>
  );
}

export default App;

I tried to set initial state for qty. i expect the all input fields to be a number 0 instead of string or undefined

2

Answers


  1. This is because of this line

    let sum = 0
    list.forEach((item) => {
      sum += item.price * qty[item.name]
    })
    

    Initially qty is an empty object so inside the above loop qty[item.name] will throw undefined.

    You need to put this iteration probably inside handleChange function or iterate the list once qty has data

    Login or Signup to reply.
  2. Putting it inside handleChange won’t work because while that function is running it still only has access to the previous version of the qty state, which is still just an empty object.

    A simple workaround would be to add an existence check while summing:

    let sum = 0;
    list.forEach((item) => {
      if (qty.hasOwnProperty(item.name)) {
        sum += item.price * qty[item.name];
      } else {
        // however you want to handle the default case here
      }
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search