Callum
Callum

Reputation: 1165

ReactJS display data from Wordpress API

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

Answers (3)

Mateus Ferreira
Mateus Ferreira

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

Mayank Shukla
Mayank Shukla

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

Vitalii Andrusishyn
Vitalii Andrusishyn

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

Related Questions