Reputation: 31
I'm new to React and having some issues of how to access a nested array inside of an object. What I want to do is render the 'name' object inside the data object exported from another file.
However, I keep getting a "undefined" error when I try to access the array nested inside the object.
When I try to just print the object I get the expected result. Equally, when I try to access the array outside the Render function it works, but for some reason I don't understand it't not working inside the render function.
My guess is that there is something about objects/arrays in React I'm not understanding.
I've also tried using .map but the result is the same.
Any clue as to what I'm not understanding?
Code looks like this:
import React from 'react';
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import {data} from './RandomData';
export default class Building extends React.Component {
constructor(){
super();
this.state = {
isLoaded: false,
selectedBuilding: '',
housingData:{}
}
}
componentDidMount(){
this.timeoutId = setTimeout(() => {
this.setState({
isLoaded: true,
error: null,
housingData: data,
selectedBuilding: data.buildings[0].name
} );
} ,3000);
}
componentWillUnmount(){
clearTimeout(this.timeoutId);
}
render(){
const loading = (<h1>loading...</h1>);
const loadingComplete = (
<Row>
<Col>{this.state.housingData ? <h1>{this.state.housingData.buildings[0].name}</h1> : ''}</Col>
</Row>
);
return (
<Container fluid>{this.state.isLoaded ? loadingComplete : loading}</Container>
)
}
}
RandomData.js:
export const data = {buildings :
[
{
name: "something1",
id: 1,
members:
{
id: 1,
firstName: "Hans",
lastName: "Ottoson",
personNumber: 198703259715
}
},
{
name: "something2",
id: 2,
members:
{
id: 1,
firstName: "Clase",
lastName: "Boson",
personNumber: 195304251985
}
}
]
}
The ERROR I get is "TypeError: Cannot read property '0' of undefined"
61 | <Row>
> 62 | <Col>{this.state.housingData ? <h1>{this.state.housingData.buildings[0].name}</h1> : ''}</Col>
63 | </Row>
64 | </Row>
65 | );
If I change:
<Row>
<Col>
{this.state.housingData ? <h1>{this.state.housingData.buildings[0].name}</h1> : ''}
</Col>
</Row>
To:
<Row>
<Col>
{this.state.housingData ? <h1>{JSON.stringify(this.state.housingData.buildings)}</h1> : ''}</Col>
</Row>
The object get printed like this:
[{"name":"something1","id":1,"members":{"id":1,"firstName":"Hans","lastName":"Ottoson","personNumber":198703259715}},{"name":"something2","i":2,"members":{"id":1,"firstName":"Clase","lastName":"Boson","personNumber":195304251985}}]
Upvotes: 0
Views: 1363
Reputation: 816334
The first time your component renders, this.state.housingData
is an empty object so this.state.housingData[0]
is indeed undefined
.
If I change [...] To [...] The object get printed like this [...]
You are seeing the output of the second render of the component. That "works" because the code change doesn't cause an error anymore in the first render of the component.
Here is a simplified example of your problem:
var housingData = {};
housingData ? housingData[0].foo : null
One possible solution is to improve your condition. Instead of just checking whether this.state.housingData
is truthy, make sure that it actually contains elements (this.state.housingData.length > 0
).
Additionally, initializing it as an array would probably make more sense as well.
var housingData = [];
housingData.length > 0 ? housingData[0].foo : null
Upvotes: 1