Reputation: 33
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
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
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