1

Updated

I am learning react so using omdbapi api want to fetch data but getting TypeError: Cannot read property 'map' of undefined

Kindly help how to solve this issue

class App extends React.Component {
  constructor(){
    super()
    this.state={
      data:[],
    }
  }
  componentDidMount(){
    fetch('http://www.omdbapi.com/?i=tt3896198&apikey=key123')
    .then((Response)=>Response.json())
    .then((findresponse)=>
    {
     this.setState({
       data:findresponse.movie
     })
      })
  }
  render() {
  return (
    <div>
      {this.state.data.map((dynamicData)=> 
      <div>
        <img src={dynamicData.Poster} alt=""/>
        <p>{dynamicData.title} </p>
        <p>{dynamicData.Released} </p>
      </div>
      )}
    </div>
  )
}
}

After below answer i have updated the source code now in html output is blank but in console.log showing the output

I want to loop 20 movies

componentDidMount(){
    fetch('http://www.omdbapi.com/?apikey=mykey&s=batman')
    .then((Response)=>Response.json())
    .then((findresponse)=>
    {
      console.log(findresponse)
     this.setState({
      data:[findresponse]
     })
      })
  }
  render() {
  return (
    <div>
      {this.state.data && this.state.data.map((dynamicData , key)=> 
      <div key={key}>
        <img src={dynamicData.Poster} alt=""/>
        <p>{dynamicData.Title} </p>
        <p>{dynamicData.Released} </p>
      </div>
      )}
    </div>
  )
}
}
2
  • 1
    What does your findresponse.movie look like? Commented May 29, 2020 at 7:41
  • Yes, check the object shape of findresponse.movie to ensure it's an array that can be mapped. Also, remember to give each mapped element a unique react key. Commented May 29, 2020 at 7:45

2 Answers 2

1

Issue :

As per the api, it returns only one movie object, and it dosen't have movie key either, so you can't map through the json object it should be array.

// response is taken from http://www.omdbapi.com/?i=tt3896198

{
    "Title": "Guardians of the Galaxy Vol. 2",
    "Year": "2017",
    "Rated": "PG-13",
    "Released": "05 May 2017",
    "Runtime": "136 min",
    "Genre": "Action, Adventure, Comedy, Sci-Fi",
    "Director": "James Gunn",
    "Writer": "James Gunn, Dan Abnett (based on the Marvel comics by), Andy Lanning (based on the Marvel comics by), Steve Englehart (Star-Lord created by), Steve Gan (Star-Lord created by), Jim Starlin (Gamora and Drax created by), Stan Lee (Groot created by), Larry Lieber (Groot created by), Jack Kirby (Groot created by), Bill Mantlo (Rocket Raccoon created by), Keith Giffen (Rocket Raccoon created by), Steve Gerber (Howard the Duck created by), Val Mayerik (Howard the Duck created by)",
    "Actors": "Chris Pratt, Zoe Saldana, Dave Bautista, Vin Diesel",
    "Plot": "The Guardians struggle to keep together as a team while dealing with their personal family issues, notably Star-Lord's encounter with his father the ambitious celestial being Ego.",
    "Language": "English",
    "Country": "USA",
    "Awards": "Nominated for 1 Oscar. Another 15 wins & 56 nominations.",
    "Poster": "https://m.media-amazon.com/images/M/MV5BNjM0NTc0NzItM2FlYS00YzEwLWE0YmUtNTA2ZWIzODc2OTgxXkEyXkFqcGdeQXVyNTgwNzIyNzg@._V1_SX300.jpg",
    "Ratings": [
        {
            "Source": "Internet Movie Database",
            "Value": "7.6/10"
        },
        {
            "Source": "Rotten Tomatoes",
            "Value": "85%"
        },
        {
            "Source": "Metacritic",
            "Value": "67/100"
        }
    ],
    "Metascore": "67",
    "imdbRating": "7.6",
    "imdbVotes": "537,920",
    "imdbID": "tt3896198",
    "Type": "movie",
    "DVD": "22 Aug 2017",
    "BoxOffice": "$389,804,217",
    "Production": "Walt Disney Pictures",
    "Website": "N/A",
    "Response": "True"
}

Solution :

For : from http://www.omdbapi.com/?i=tt3896198

// as there is no `movie` key change `findresponse.movie` to `findresponse`

// if you want to use it as array for only one object
this.setState({
    data:[findresponse]
    // OR
    data : [...this.state.data , findresponse] // <--- If you want pushing result with previous 
})

// suggested
this.setState({
    data : findresponse
})

For : http://www.omdbapi.com/?apikey=YOUR_KEY&s=Batman , you can use the below one

this.setState({
    data : findresponse.Search
})
Sign up to request clarification or add additional context in comments.

4 Comments

after changing the setState movie data is showing how to loop the data like if i want 10 movie because right now only one movie showing
@Viking, you will always get one movie only, if you are searching through id http://www.omdbapi.com/?i=tt3896198
i have change the api path fetch('omdbapi.com/?apikey=mykey&s=batman') and print in console.log(findresponse) the data is getting but on html its total blank <div> {this.state.data && this.state.data.map((dynamicData , key)=> <div key={key}> <img src={dynamicData.Poster} alt=""/> <p>{dynamicData.Title} </p> <p>{dynamicData.Released} </p> </div> )} </div>
for omdbapi.com/?apikey=mykey&s=batman%27 use this.setState({ data:findresponse.Search })
0

Try to check if data is not undefined first:

{this.state.data && this.state.data.map((dynamicData)=> 
  <div>
    <img src={dynamicData.Poster} alt=""/>
    <p>{dynamicData.title} </p>
    <p>{dynamicData.Released} </p>
  </div>
  )}

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.