0

There is something that I just can't figure out. Here is a basic React class-based component fetching some data from an endpoint:

import React from 'react';
import ReactDOM from 'react-dom';

class Example extends React.Component {
  state = { info: {} };

  componentDidMount() {
    fetch('https://api.spacexdata.com/v2/info')
      .then(response => response.json())
      .then(data => {
        const info = data;
        this.setState(() => ({ info }));
      });
  }

  render() {
    return (
      <div>
        {/* the first h1 renders just fine */}
        <h1>{this.state.info.name}</h1>
        {/* the second throws an error: Cannot read property 'address' of undefined */}
        <h1>{this.state.info.headquarters.address}</h1>
      </div>
    );
  }
}

ReactDOM.render(<Example />, document.getElementById('root'));

Why is the second h1 tag giving me undefined??? I check the state in the react dev tools and the data is there... It is literally an object that has another object within it... If I copy paste that same object into the state it renders just fine...

2
  • you are sure that info.name is there? what is the value of name? Commented Mar 18, 2018 at 15:10
  • @Tomasz Yes... just copy paste the url into a browser and you’ll see... it’s just on object. Seem only the nested object within it throws an error... Commented Mar 18, 2018 at 20:57

1 Answer 1

1

The problem is the async nature of the promises, when you first render the component you start the promise but it will take some time to execute and resolve, so it didn't return the JSON yet.This means that info still being {} and when you try to render your H1

<h1>{this.state.info.headquarters.address}</h1>

you will get the undefined error. Because this.state.info.headquarters is undefined so you cannot access .address until the promise resolves(remember they are async)

just replace your initial state with this one(or something similar)

state = { info: {headquarters:{address:'loading...'} };

and you will be fine.

Sign up to request clarification or add additional context in comments.

3 Comments

Then why does the first H1 render? Only when trying to render the second does it throw the undefined error...
Because in the first one you have the object info. And when you try to access name it returns unrefined. What is fine. Only when you try to go down one more level you get the error. Because then you are trying to access an property of undefined, and this causes the error.
Got it. I actually did {this.state.info.headquareters ? this.state.info.headquarters.address : ‘Loading...’ }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.