2

how to I get the property of an array of objects in the render function. if I try this:

render() {
    console.log(this.state.items[0].name);
 (...)

I got an error:

TypeError: this.state.items[0] is undefined

  class App extends React.Component {
  constructor() {
    super()

    this.state = {
      items: []
    }
  }
  componentWillMount() {
    fetch('http://swapi.co/api/people/?format=json')
      .then((response) => response.json())
        .then(({ results: items }) => this.setState({ items }))
  }

  filter(e){
    this.setState({ filter: e.target.value })
    console.log(this.state.items[0].name);
  }

  render() {
    console.log(this.state.items[0].name);
    return (
      <div>
        <input type="text" onChange={this.filter.bind(this)}  />
      </div>
    )
  }

}
export default App

However, if I log out only the first element of the array

 console.log(this.state.items[0])

it prints out the object

Object { name: "Luke Skywalker", height: "172", mass: "77", hair_color: "blond", skin_color: "fair", eye_color: "blue", birth_year: "19BBY", gender: "male", homeworld: "http://swapi.co/api/planets/1/", films: Array[5], 6 more… }

When the filter function get fired I do get the property of the first element console.log(this.state.items[0].name)

prints out:

Luke Skywalker

What's happening here?

0

2 Answers 2

2

Your state.items array is not set until your fetch has completed. Your render method will be called prior to this, therefore, it won't work as expected.

If you recheck your console output, I have a feeling you'll see some nulls or undefined's prior to the your object showing.

Try this:

 render() {
    console.log(this.state.items.length > 0 ? this.state.items[0].name : 'Items not loaded yet');
    return (
      <div>
        <input type="text" onChange={this.filter.bind(this)}  />
      </div>
    )
  }
Sign up to request clarification or add additional context in comments.

Comments

1

fetch is asynchronous call, so during first time rendering this.state.items will [] and you are trying to access the name of 0th item that doesn't exist, and it is throwing the error because of that.

When you are using:

console.log(this.state.items);

Check the console it was printing two values one [] and another one will be the data that you are getting from server.

Solution:

Put the check on length inside render it will print the proper name once you get the response.

Like this:

render(){
   if(this.state.items.length)
       console.log(this.state.items[0].name);

   return(
       ....
   )
}

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.