Home > Software design >  Rendering array of objects having default values, declared using useState is not working while displ
Rendering array of objects having default values, declared using useState is not working while displ

Time:08-08

I have one users array of objects declared using useState as show below:

  const [users, setUsers] = useState([
    {
      prn: 12,
      name: "Shrut",
      gender: "M",
      mobile: 1234567890,
      dept: "CSE",
      year: "First",
      sem: "Second"
    },
    {
      prn: 13,
      name: "Shrutika",
      gender: "M",
      mobile: 1234567890,
      dept: "CSE",
      year: "First",
      sem: "Second"
    }
  ]);

And I am trying to display this value using map inside table but getting error that Cannot read properties of undefined (reading prn)

<tbody>
    {     
        users.map((obj, index) => {

            return (
                <tr key={index}>
                    <td>{obj.prn}</td>
                    <td>{obj.name}</td>
                    <td>{obj.gender}</td>
                </tr>
            )
        })
    }
</tbody>

CodePudding user response:

You have an error in onDeleteSubmit

You used map but you wanted to use filter

const onDeleteSubmit = (id) => {
    var updatedUsers = users.filter((obj, index) => {
      if (index != id) {
        return obj;
      }
    });
    setUsers(updatedUsers);
  };

Your users array looked like this after this operation (2) [Object, undefined] which caused the error

CodePudding user response:

Posting this answer so that if in future anyone getting same error it might help you. My half of the problem is solved by @Konrad Linkowski (https://stackoverflow.com/a/73269803/11712874)

After correcting above mistake, my type error resolved but still I was not able to display data in users. Below was my code:

users.map((obj, index) => { 
    return (
        <tr key={index}>
            <td>{obj.name}</td>                 
            <td>
                // conditional rendering of select tag or actual value of 
                obj.dept
            </td>
            <td>
                {
                    changeElementsOnUpdate == index ?
                        <input type="button" value="Done" disabled={disableButton}
                            onClick={onUpdateSubmit(index)}
                         />
                    :
                        <input type="button" value="Update" disabled={disableButton}
                            onClick={setChangeElementsOnUpdate(index)}
                        />
                }
            </td>
            <td>
                <input type="button" value="Delete" disabled={disableButton}
                        onClick={onDeleteSubmit(index)}
                />
            </td>
        </tr>
    )
})

By playing with the code, I observed that I am calling useState functions onClick without using callback. And that's the reason of the entire mess.

So I changed all calls as shown in the below sample:

<td>
    <input type="button" value="Delete" disabled={disableButton}
        onClick={() => {
            onDeleteSubmit(index)
        }}
    />
</td>
  • Related