0

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}}]
niwim
  • 21
  • 7

1 Answers1

1

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
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Thanks a million I was getting bald with this... Truthy and falsy has caught me out more times than it should. Need learn more about it! Yes it makes more sense to initialise housingData as an array! Big thanks again! – niwim May 12 '21 at 09:39
  • @Felix Hello sir, could you help me on https://stackoverflow.com/questions/67498940/input-field-losing-focus-on-each-character-type-react – Aayush Dahal May 12 '21 at 10:30