lucem
lucem

Reputation: 33

Can not access properties in JavaScript object array (React.js)

I have a React.js component which pulls its initial state data from an API call in componentDidMount(). The data is an array of objects.

I am able to view the array, and individual elements using JSON.stringify (for debugging), but when I try to access a property in an element, I get an error which seems to imply that the element is undefined, despite having checked that it is not.

Code:

class TubeStatus extends Component {
  constructor(props) {
    super(props);
    this.state = { 'tubedata' : [] };
  };
  componentWillMount() {
    let component = this;
    axios.get('https://api.tfl.gov.uk/line/mode/tube/status')
    .then( function(response) {
      component.setState({ 'tubedata' : response.data });
    })
    .catch( function(error) {
      console.log(JSON.stringify(error, null, 2));
    });
  };
  render() {
    return (
      <div><pre>{this.state.tubedata[0].id}</pre></div>
    );
  }
}

Error:

Uncaught TypeError: Cannot read property 'id' of undefined

If I use JSON.stringify() to display this.state.tubedata, all the data is there.

In my admittedly limited knowledge of React.js, I suspect this is because React.js is trying to access the .id property before componentDidMount() fires loading the initial state data, thus returning undefined, but I could be completely wrong.

Anyone able to point me in the right direction?

Upvotes: 3

Views: 3388

Answers (2)

Shubham Khatri
Shubham Khatri

Reputation: 281636

this is because you are having a async request and since the state array is initially empty this.state.tubedata[0] is initially undefined

Keep a check before using id like

<div><pre>{this.state.tubedata.length > 0 && this.state.tubedata[0].id}</pre></div>

class TubeStatus extends React.Component {
  constructor(props) {
    super(props);
    this.state = { 'tubedata' : [] };
  };
  componentWillMount() {
    let component = this;
    
  };
  render() {
    return (
      <div>Hello <pre>{this.state.tubedata.length > 0 && this.state.tubedata[0].id}</pre></div>
    );
  }
} 
ReactDOM.render(<TubeStatus/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Upvotes: 1

Ved
Ved

Reputation: 12093

As you are fetching data from API call, on initial rendering data is not available hence you are getting error.

this.state.tubedata.length>0// check if tubedata is available 

So,

 render() {
    return (
      <div><pre>{this.state.tubedata.length>0?this.state.tubedata[0].id:null}</pre></div>
    );
  }

Upvotes: 3

Related Questions