I have written a small react component which fetches some data from the open weather api. The fetch succeeds and I can get a json object in the response.
I then save this response to the components state using this.setState({})
And the react dev tools show the forecast object is infact saved in state.
However when I come to rendering any of the data i always get an error stating `cannot read property 'forecast' of null.
Below is the react component and a screen shot of the object itself.
export default class Weather extends Component {
getWeather () {
var self = this;
fetch('http://api.openweathermap.org/data/2.5/weather?zip=sl44jn,uk&units=metric&APPID=ed066f80b6580c11d8d0b2fb71691a2c')
.then (function (response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + response.status);
return;
}
response.json().then(function(data) {
self.setWeather(data);
});
})
.catch (function (err) {
console.log('Fetch Error :-S', err);
});
}
setWeather (forecast) {
console.log(forecast);
this.setState({
forecast: forecast.name
})
}
componentWillMount () {
this.getWeather();
}
componentDidMount () {
// window.setInterval(function () {
// this.getWeather();
// }.bind(this), 1000);
}
render() {
return (
<h1>{this.state.forecast}</h1>
)
}
}
And this is the data object itself, right now I am simply trying to access the name attribute.
In that case, you can use the getAttribute() method. The getAttribute() method will return the string value of the specified attribute. Alternatively, you can also access attributes using the getNamedItem() method.
If we want to access all the values of nested objects then we have to use recursion to access each and every level of that object. And it can get more complicated according to the nesting of the object. That why we have to use recursion to get all the values and access the whole nested object.
Purpose of render(): React renders HTML to the web page by using a function called render(). The purpose of the function is to display the specified HTML code inside the specified HTML element. In the render() method, we can read props and state and return our JSX code to the root component of our app.
We can't render an object, but we can render strings. What if we turn the object into a string and render it then? We can do that with JSON. stringify (docs).
Looks like you forgot couple of things, in order to a Component
to setState
you need to bind it to this
preferably in the constructor. You also need to set the initial state, in your case an empty object, and you can save the whole response in the object and access just the parts you want. have a look:
export default class Weather extends Component {
constructor() {
super();
this.state = {
forecast: {}
};
this.setWeather = this.setWeather.bind(this);
}
getWeather () {
let self = this;
fetch('http://api.openweathermap.org/data/2.5/weather?zip=sl44jn,uk&units=metric&APPID=ed066f80b6580c11d8d0b2fb71691a2c')
.then (function (response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + response.status);
return;
}
response.json().then(function(data) {
self.setWeather(data);
});
})
.catch (function (err) {
console.log('Fetch Error :-S', err);
});
}
setWeather (forecast) {
this.setState({
forecast: forecast
});
}
componentWillMount() {
this.getWeather();
}
render() {
const { forecast } = this.state;
return (
<h1>{forecast.name}</h1>
)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With