0

I'm trying to map an array of movies which I get from an API.

The data is fetched successfully but when I try to map the values and display, it becomes undefined and does not show anything.

I'm new to React so any help and advice would be helpful.

const [items, setItems] = useState([]);

const getMovieData = () => {
  axios
    .get(api_url)
    .then((response) => {
      const allMovies = response.data;
      console.log(allMovies);
      setItems(allMovies);
    })
    .catch((error) => console.error(`Error: ${error}`));
};

useEffect(() => {
  getMovieData();
}, []);

return (
  <div>
    {items.map((item) => {
      <p>{item.title}</p>;
    })}
  </div>
);

The data is stored like this:

0: {
  adult: false, 
  backdrop_path: '/9eAn20y26wtB3aet7w9lHjuSgZ3.jpg', 
  id: 507086, 
  title: 'Jurassic World Dominion', 
  original_language: 'en',
  ...
}
2

3 Answers 3

3

You're not returning anything from your map

{ 
  items.map((item) => {
   // Add a return
   return <p>{item.title}</p>
  })
}
Sign up to request clarification or add additional context in comments.

Comments

1

First, your items value is an empty array[] as you have initialized with setState([]) and your useEffect() runs only after your component is rendered which means even before you could do your data fetching, your HTML is being displayed inside which you are trying to get {item.title} where your items is an empty array currently and hence undefined. You will face this issue often as you learn along. So if you want to populate paragraph tag with item.title you should fast check if your items is an empty array or not and only after that you can do the mapping as follow and also you need to return the element from the map callback. If it takes some time to fetch the data, you can choose to display a loading indicator as well.

const [items, setItems] = useState([]);
const getMovieData = () => {
  axios.get(api_url)
    .then((response) => {
      const allMovies = response.data;
      console.log(allMovies);
      setItems(allMovies);
    }).catch(error => console.error(`Error: ${error}`));
};

useEffect(() => {
  getMovieData();
}, []);
return ( < div > {
    items.length !== 0 ? items.map((item) => {
      return <p > {
        item.title
      } < /p>
    }) : < LoadingComponent / >
  }

  <
  /div>
);

Comments

0

Good catch by Ryan Zeelie, I did not see it.

Another thing, since you're using promises and waiting for data to retrieve, a good practice is to check if data is present before mapping.

Something like :

return (
    <div>
         { (items.length === 0) ? <p>Loading...</p> :  items.map( (item)=>{
         <p>{item.title}</p>
         })}
    </div>
);

Basically, if the array is empty (data is not retrieved or data is empty), display a loading instead of mapping the empty array.

1 Comment

Yea good point! Additionally check the data being received, incase it comes back as undefined or null then the map will run and throw errors. const allMovies = response?.data; if(allMovies) setItems(allMovies)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.