question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot access lower leaves in object loaded with JSON and put in `this.state`

See original GitHub issue

After loading a JSON object and adding it to this.state in the manner shown in the React Tutorial, I am not able to access leaves below the first level. Given this JSON file:

{
    "simple": "A simple key-value",
    "dag1": {"key" : "A key pointing to a key-value" },
    "dag2": { "firstkey": { "secondkey": "A key pointing to a key pointing to a key-value" } }
}

the following results:

  1. {this.state.data.simple} works: “A simple key-value”
  2. {this.state.data.dag1.key} “Uncaught TypeError: Cannot read property ‘key’ of undefined”
  3. {this.state.data.dag.firstkey.secondkey} “Uncaught TypeError: Cannot read property ‘firstkey’ of undefined”

By putting debug variables in function loadJSONFromServer, one can see that that we can reference data fine from the JSON data structure itself, but not through this.state after this.setState adds it:

    this.secondkey = data.dag2.firstkey.secondkey;  // Works here!
    this.setState({data: data});
    this.secondkey2 = this.state.data.dag2.firstkey.secondkey;  // But doesn't work here!

Here is the full test file, loading the JSON above in file test-data.json. In the output, 1) and 4) work; 2) and 3) invoke the above error messages; and 5) returns nothing.

<!DOCTYPE html>
<html>
<head>
  <title>Test referencing JSON object in React state</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>

<h2>JSON Test</h2>
<div id="content"></div>

<script type="text/jsx">

var ContentBox = React.createClass({
  loadJSONFromServer: function() {
    $.ajax({
      url: this.props.url,
      dataType: 'json',
      cache: false,
      success: function(data) {
                this.secondkey = data.dag2.firstkey.secondkey;  // Works here!
        this.setState({data: data});
                this.secondkey2 = this.state.data.dag2.firstkey.secondkey;  // But doesn't work here!
      }.bind(this),
      error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
      }.bind(this)
    });
  },
    getInitialState: function() {
    return {data: ''};
  },
  componentDidMount: function() {
    this.loadJSONFromServer();
  },
  render: function() {
        // var testValue = {this.state.data.junk};
    return (
      <div>
        <h2>Test</h2>
                <p>1. {this.state.data.simple}</p>
                <p>4. {this.secondkey}</p>
                <p>5. {this.secondkey2}</p>
      </div>
    );
  }
});

React.render(
  <ContentBox url="test-data.json" />,
  document.getElementById('content')
);

</script>

</body>
</html>

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
Mark-L6ncommented, Jul 12, 2015

@jimfb, thanks for bearing with me. I finally figured out what was going on and will put it in my own words. The reason the error messages were occurring is because the 1st time that render() is getting called, the JSON object has not loaded yet, so there are not yet keys for this.state.data.dag1.key and this.state.data.dag2.firstkey.secondkey, and the error messages are produced. (So the strange thing here is that this.state.data.simple did not produce the same error message.) By adding <p>7. {this.state.data}</p> to the return values, I can see that after render() was called the final time, all of the data was there. This is the reason that in the React tutorial, there is:

getInitialState: function() {
    return {data: ''};
 },

Without this.state.data being created by getInitialState(), the same error would have occurred the 1st time render() was called. If I initialize the data structures, with for example:

getInitialState: function() {
   return { data: {
            "simple": "",
            "dag1": {"key" : "" },
            "dag2": { "firstkey": { "secondkey": "" } }
        }
    }
 },

Then render() does not fail the 1st time, and everything works.

0reactions
jimfbcommented, Jul 12, 2015

I’m confused about the comment:

Your loadJSONCallback does not appear to be calling setState…

…since loadJSONCallback is itself called by setState.

Yes, that is my point. setState() has already happened before loadJSONCallback gets called (that’s why you’re getting the callback). If you set a local variable after the last call to setState, your component will not re-render because nothing told React that your component’s state has changed. Setting a local variable in the setState callback is a really weird thing to do, not recommended. If you call setState again from within loadJSONCallback, I think it’ll force another re-render and display the data for secondkey2.

Same for for secondkey3, that line occurs after the last call to setState(), so again, it’s not going to show up in your render.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Can't access nested JSON Objects in React
API returns. state is set to result.data . result.data gets logged ... Issue is that JSON objects can be accessed one-level deep before...
Read more >
MySQL 8.0 Reference Manual :: 11.5 The JSON Data Type
Prior to MySQL 8.0.13, a JSON column cannot have a non- NULL default value. ... A JSON object contains a set of key-value...
Read more >
Using JSON.NET for dynamic JSON parsing - Rick Strahl
In this post I'll discus JToken, JObject and JArray which are the dynamic JSON objects that make it very easy to create and...
Read more >
Easily parsing JSON in R with jsonlite and purrr
The listviewer strategy can allow you to explore interactively, while the code below is more of moving through the JSON object in R....
Read more >
Loading JSON data from Cloud Storage | BigQuery
Note: When you load data into an empty table by using the Google Cloud console, you cannot add a label, description, table expiration,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found