Reputation: 1165
I am new to React so I am just trying to pull data from my wordpress website API. I am getting a generic blog post which will display this.state.post.link
fine but not any of the rendered data.
import React from 'react'
export default React.createClass({
getInitialState: function () {
return {
post: {},
}
},
componentDidMount: function () {
var _this = this;
$.get('http://somewebsite.net/wp-json/wp/v2/posts/1258', function(result) {
_this.setState({
post: result
});
});
},
render() {
console.log(this.state.post);
return <div className="single-post">
<h1>{this.state.post.link}</h1>
<h1>{this.state.post.title.rendered}</h1>
</div>
}
});
I get this error from adding post.title.rendered
.
bundle.js:51835 Uncaught TypeError: Cannot read property 'rendered' of undefined
This is what shows with the code console.log(this.state.post.title);
Object {rendered: "Example post"}
So why can I console.log this.state.post.title and it shows the object with rendered in but then if I try and display that it will say title is undefined?
Upvotes: 1
Views: 1540
Reputation: 529
Define the initial state for title.rendered
as a empty string.
this.state = {
post: {
title: {
rendered: ''
}
}
...
render() {
return (
<div>
{this.state.post.title.rendered}
</div>
)
}
OR
Check if the state is defined before rendering:
render() {
return (
<div>
{this.state.post ? this.state.post.title.rendered : null }
</div>
)
}
Upvotes: 4
Reputation: 104379
Reason is you are fetching the data from api, until you didn't get the data, this.state.post.title
will be undefined
, and you are trying to access rendered
of undefined
, that's why it is throwing the error:
Cannot read property 'rendered' of undefined
ajax
call is asynchronous
call, it will take time to fetch the data and render
method will get called before that.
One solution is, put the check on this.state.post.title
:
render() {
console.log(this.state.post);
return <div className="single-post">
<h1>{this.state.post.link}</h1>
<h1>{this.state.post.title && this.state.post.title.rendered}</h1>
</div>
}
Or hold the complete rendering until you didn't get the data, by putting the check on this.state.post
inside render
method.
Update-
Define the initial value of post as null
:
getInitialState: function () {
return {
post: null,
}
},
Then check the value of post inside render
method, it will not rendering anything until you didn't get the response:
render() {
console.log(this.state.post);
if(!this.state.post) return null;
return <div className="single-post">
<h1>{this.state.post.link}</h1>
<h1>{this.state.post.title.rendered}</h1>
</div>
}
Note: There is one issue with this, rendered
key must be present inside title
in response otherwise it will also throw the same error.
Upvotes: 2
Reputation: 4162
maybe this will be helpful:
render() {
console.log(this.state.post);
var link = (this.state.post && this.state.post.link) ? this.state.post.link : '';
var rendered = (this.state.post && this.state.post.title && this.state.post.title.rendered) ? this.state.post.title.rendered : '';
return <div className="single-post">
<h1>{link}</h1>
<h1>{rendered}</h1>
</div>
}
Upvotes: 0