Cannot access lower leaves in object loaded with JSON and put in `this.state`
See original GitHub issueAfter 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:
{this.state.data.simple}
works: “A simple key-value”{this.state.data.dag1.key}
“Uncaught TypeError: Cannot read property ‘key’ of undefined”{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:
- Created 8 years ago
- Comments:7 (3 by maintainers)
Top 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 >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@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 forthis.state.data.dag1.key
andthis.state.data.dag2.firstkey.secondkey
, and the error messages are produced. (So the strange thing here is thatthis.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 afterrender()
was called the final time, all of the data was there. This is the reason that in the React tutorial, there is:Without
this.state.data
being created bygetInitialState()
, the same error would have occurred the 1st timerender()
was called. If I initialize the data structures, with for example:Then
render()
does not fail the 1st time, and everything works.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.