Avi Jain Avi Jain - 5 months ago 37
JSON Question

Error while assigning JSON data to variable and accessing it through the state in React

I recently started with React.js and have been trying build a simple weather app. Had no issues with the GET request, as the console is printing out the JSON string received from the OpenWeatherMap API, but there seems to be an issue with assigning the JSON to a local variable and then accessing its properties.

getInitialState : function(){
return (
{weatherdata: null }
);
},

componentWillMount : function(){
HttpService.get()
.then(function(jsondata){
console.log(jsondata);
this.setState({weatherdata : jsondata});
}.bind(this));
},


The console gives me 2 errors and the react dev tools refuse to load :
Uncaught TypeError: Cannot read property 'main' of null

Uncaught (in promise) TypeError: Cannot read property '_currentElement' of null(…)

The first one points me to the line

React.createElement(Today, { temp: this.state.weatherdata.main.temp,

Here's a snippet of the return inside the render function

return(
<div>
<Today temp={this.state.weatherdata.main.temp}
windSpeed={this.state.weatherdata.wind.speed}
windAngle={this.state.weatherdata.wind.deg}
icon={this.state.weatherdata.weather[0].icon}
iconID={this.state.weatherdata.weather[0].id}
iconDesc={this.state.weatherdata.weather[0].description} />
</div>
);


Now, if I directly paste all the data inside the weatherdata object, it seems to work fine.

Have tried JSON.parse(), but that does not seem to resolve the issue. Any help would be appreciated.

Answer

you are requesting something as an async process but expecting it to be rendered before the data comes in.

try returning null until the data comes in

if(!this.state.weatherdata){
    return null;
}
return(
    <div>
        <Today  temp={this.state.weatherdata.main.temp}
                windSpeed={this.state.weatherdata.wind.speed}
                windAngle={this.state.weatherdata.wind.deg}
                icon={this.state.weatherdata.weather[0].icon}
                iconID={this.state.weatherdata.weather[0].id}
                iconDesc={this.state.weatherdata.weather[0].description} />
     </div>
);

That being said I would recommend you use a library like lodash that has a get method. It will improve the stability of your code tremendously by removing javascript errors. The get method takes a variable and searches for a path on it.

EX:

var test = {john: ['billy', 'bob']};
console.log(_.get(test, 'john[1]'); // prints 'bob'
console.log(_.get(test, 'john[2]'); // prints 'undefined'
console.log(_.get(test, 'john[2].something.somethingElse'); // prints 'undefined'

this is what it would look like if you used lodash.

var weatherData = this.state.weatherdata;
return(
    <div>
        <Today  temp={_.get(weatherData, 'main.temp')}
                windSpeed={_.get(weatherData, 'wind.speed')}
                windAngle={_.get(weatherData, 'wind.deg')}
                icon={_.get(weatherData, 'weather[0].icon')}
                iconID={_.get(weatherData, 'weather[0].id')}
                iconDesc={_.get(weatherData, 'weather[0].description')} />
     </div>
);