-1

I'm trying to build a products page with list of products with their details fetched from an external API and being displayed as cards. I looked through how to do it and found this to be similar to what I wanted to do but I mimicked the code in this post React fetch api data to component and I'm getting an error TypeError: Cannot read property 'map' of undefined

Products component

class Products extends Component {
    constructor(props){
        super(props);
        this.state = {
            items: [],
            isLoaded: false,
        }
    };
    componentDidMount = () => {
        fetch("https://api.themoviedb.org/3/movie/popular?api_key=xxxxxxxx&page=1")
        .then(resp => resp.json())
        .then(resp => {
            this.setState({
                isLoaded: true,
                items: resp.results
            })
            console.log(this.state.items)      
    })};

   
      render() {
        var {isLoaded, items} = this.state;
        
        return (
            <div>
                {items.map(item => (<Card key={item.id} item={item} />))};
            </div>
        );
    }
  
}

export default Products;

Card Component

const Card = (props) => {
    const { item } = props;
    return (
        <div className="movie-container">
            <img src="https://image.tmdb.org/t/p/w185/{items.poster_path}" alt="NO PHOTO" className="movie-container__img" />
            <div className="movie-container__about">
                <span className="movie-container__percent">{item.vote_average}</span>
                <h2 className="movie-container__title">{item.original_title}</h2>
                <p className="movie-container__date">{item.release_date}</p>
                <p className="movie-container__text">{item.overview}</p>
                <a href="https://www.themoviedb.org/movie/" className="movie-container__more">MORE</a>
            </div>
        </div>
    )
}

export default Card;
2
  • items is undefined, likely because resp.results is undefined. Commented Mar 29, 2021 at 8:39
  • what should I set the items to then? Commented Mar 29, 2021 at 9:04

1 Answer 1

0

It seems that if render() executes, state.items can be null or undefined, most likely as a result of what your API returns, or how you process what it returns.

The reason to 'blame' the API is because you initialize items to [] in the constructor, so initially there is an array and calling map will work.

To fix this, check if items has a value; if not then don't show anything. And then check if you access the API correctly, perhaps also dive into the API to see what it does and fix it.

It would also be good to check isLoaded so you don't show data unless the API call has finished.

render() {
    var {isLoaded, items} = this.state;

    if (!isLoaded || !items)
        return null; // or if you like, show a "Waiting" indicator

    return (
        <div>
            {items.map(item => (<Card key={item.id} item={item} />))};
        </div>
    );
}
Sign up to request clarification or add additional context in comments.

Comments

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.