1

I am trying to access variables from json in react component.

This is JSON I am getting:

{
    "id": 5,
    "title": "Hello",
    "text": "Hello, this is my first article...",
    "picture": "pic",
    "comments": [],
    "user": {
        "id": 3,
        "name": "Anonim",
        "password": "123456"
    }
}

The attached user is person who created the post. The attached comments is list of comments related to this post. In routing I am doing the following:

    <Switch>
      <Route path='/' exact component={PostsPage} />
      <Route path='/:id' exact component={PostProfilePage} />
    </Switch>

In react class component

class PostProfile extends Component {

  constructor(props){
    // Pass props to the parent component
    super(props);
    // Set initial state
    this.state = {
      // State needed
      post: []
    };
  }

  componentDidMount() {
    this.fetchPost();
  }

  fetchPost() {
    const {match} = this.props
    const id = match.params.id
    console.log(id)
    fetch('/'+id)
    .then(res => {
      return res.json();
    })
    .then(data => {
      this.setState({
        post: data
      });
    })
    .catch(err => {
      console.log(err);
    });
  }

  render() {
    return (
      <div>
      <li> {this.state.post.title} </li>
      <li> {this.state.post.text} </li>
      </div>
    )
  }
}

export default withRouter(PostProfile)

does not work

 <li> {this.state.post.user.name} </li>
  <li> {this.state.post.comments...} </li>

Why I cannot access user and comments? And is it possible to get user and comments in different components? (not calling the fetch method again and again)?

Thank you in advance!

4
  • Does this.state.post yield anything? Commented Oct 21, 2017 at 16:43
  • yes, the same as JSON Commented Oct 21, 2017 at 16:46
  • don't show any error on console? on the first render? Commented Oct 21, 2017 at 16:57
  • I put console.log(this.state.post.user.name) and console.log(this.state.post.user) in render. it shows this.state.post.user but not the first one. Commented Oct 21, 2017 at 17:04

1 Answer 1

1

Your post at first time has no data, so you need something like:

import React, { Component } from 'react';

export default class Test extends Component {
  constructor(props) {
    // Pass props to the parent component
    super(props);
    // Set initial state
    this.state = {
      // State needed
      post: []
    };
  }

  componentDidMount() {
    this.fetchPost();
  }

  fetchPost() {

    fetch('https://swapi.co/api/people/1')
      .then(res => {
        return res.json();
      })
      .then(data => {
        this.setState({
          post: data
        });
      })
      .catch(err => {
        console.log(err);
      });
  }

  render() {
    const show = this.state.post.length === 0 ? 
      <h1> ...loading </h1> 
      : <h1> {this.state.post.birth_year} </h1> 
    return (
      <div>
        <h1> { show } </h1>
      </div>
    )
  }
}

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you! Now I also can return different parts separately!
I am really sorry, but I need to ask one thing more. Is it possible to get another condition with the same logic inside const condition. because now I have the same problem when load array of comments. I tried, but the syntax is wrong
Alright, put the logic inside a function that returns loading... Or anything. You can do with a lot of possible.
Here javascriptplayground.com/blog/2017/07/react-extracting-logic a example how and where put your logic

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.