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

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

I can view the array and individual elements using JSON.stringify (for debugging), but when I try to access a property on the element, I get an error that seems to imply that the element is undefined despite checking 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>
    );
  }
}

      

Mistake:

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 notoriously limited knowledge of React.js, I suspect this is because React.js is trying to access the .id property before componentDidMount () triggers loading the initial state data, thus returning an undefined value, but I could be completely wrong.

Can anyone point me in the right direction?

+3


source to share


2 answers


How do you retrieve data from an API call when the initial render data is not available, so you get an 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>
    );
  }

      

+4


source


this is because you have an async request and since the states array is initially empty it is this.state.tubedata[0]

initially undefined

Save validation 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>
      

Run codeHide result


+1


source







All Articles