Cannot read property 'map' of undefined

Viewed 163

I have an error of Cannot read property of map, I'm trying to display a table of content on my page by getting the data from the database using restful API and store it into an array. first time I open the site everything works fine and it displays the table with no problem but when I refresh it gives the error.

This is my function for getting the data and display it in a table using map:

const ListTodos = ()=>{
    const [todos,setToods]=useState([]);
   
        const getTodos = async ()=>
        {
            try{
                const res = await fetch("http://localhost:3080/get")
                
                console.log(res)
                   const jsondata = await res.json();
                   setToods(jsondata);
            }catch(err){
              
                console.error(err.message);
            }
        }


        useEffect(() => {
            getTodos();
          }, []);
          
          arr = todos[0];

 
      
      return (
          <Fragment>
      <table class="table mt-5 text-center">
        <thead>
        <tr>
            <th>ID_Event</th>
            <th>Name_Event</th>
            <th>Date</th>
            <th>Address</th>
            <th>Duration</th>
            <th>Description</th>
            <th>Delete</th>
            <th></th>
          </tr>
        </thead>
        <tbody>
        
        {arr.map(arr => (
            <tr>
              <td>{arr.ID_Event}</td>
              <td>{arr.Name_Event}</td>
              <td>{arr.Date}</td>
              <td>{arr.Address}</td>
              <td>{arr.Duration}</td>
              <td>{arr.description}</td>
              <td>
              <button className="btn btn-danger" onClick={() => deleteevnet(arr.ID_Event)}>Delete</button>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </Fragment>
                );
      }
3 Answers

By writing arr = todos[0] on top level you are creating a global variable which is undefined until the data is fetched (first element of empty array).

You should declare it ideally as const so it is local to the functional component, and handle the case when it's undefined with something like:

{arr && arr.map(arr => (
            <tr>
              <td>{arr.ID_Event}</td>
              <td>{arr.Name_Event}</td>
              <td>{arr.Date}</td>
              <td>{arr.Address}</td>
              <td>{arr.Duration}</td>
              <td>{arr.description}</td>
              <td>
              <button className="btn btn-danger" onClick={() => deleteevnet(arr.ID_Event)}>Delete</button>
              </td>
            </tr>
          ))}

Add a conditional so it runs when your arr is not undefined:

{arr !== "undefined" && arr.map(arr => (

React evaluates our return statement, when it hits the arr.map(...) line its actually running undefined.map(...) which is obviously an error in JavaScript.

Read more here

Use the following programming construct to ensure the arr has value inside it:

{arr && arr.map(arr => (
  // ...
))}

The useEffect hook works asynchronously so on the first run the arr would be undefined:

arr = todos[0]; // [][0] === undefined
Related