DTek
DTek

Reputation: 371

Can't get JSON list ReactJS from fetch

Hello guys I'm using the Star Wars API to experiment in ReactJS.

I wanna to get the collection of people that comes in the form:

{
    "count": 87,
    "next": "https://swapi.co/api/people/?page=2",
    "previous": null,
    "results": [
        {
            "name": "Luke Skywalker",
            "height": "172",
            "mass": "77",
            "hair_color": "blond",
            "skin_color": "fair",
            "eye_color": "blue", ... (continues)

Since I can fetch a single character I know the mechanism of fetch is working, but I'm failing to get the list of characters in results.

My app goes like:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Character from './Character'
class App extends Component {
  constructor() {
    super()
    this.state = {
      people : {},
      character: {}
    }
    fetch("https://swapi.co/api/people/1")
            .then(response => response.json())
            .then(data => {
                this.setState({
                    character: data
                })
            })

    fetch("https://swapi.co/api/people/")
            .then(response => response.json())
            .then(data => {
                this.setState({
                    people: data
                })
            })
    console.log(this.state.people)
    console.log(this.state.people.results)
  }
  render() {
    return (
      <div className="App">
        <Character
          character = { this.state.character}
        />
      </div>
    );
  }
}

export default App;

I'm getting this information from the console.log's (the rest is for the single character which is working fine).

The first console.log gives me an (in firefox webconsole)

Object { }

The second gives me undefined.

I've experimented a bunch of stuff and can't seem to find how to get that list of characters..what am I missing?

Upvotes: 0

Views: 887

Answers (2)

Paul Fitzgerald
Paul Fitzgerald

Reputation: 12129

You should use this as an opportunity to use React hooks. It's the future 🚀

const App = () => {
    // equivalent to the state object in your constructor
    const [people, setPeople] = React.useState({});
    const [character, setCharacter] = React.useState({});

    // as second argument is an empty array it is
    // the equivalent of componentDidMount
    React.useEffect(() => {
       fetch("https://swapi.co/api/people/1")
         .then(response => response.json())
         .then(data => {
             setCharacter(data);
          }
        )

        fetch("https://swapi.co/api/people/")
          .then(response => response.json())
          .then(data => {
            setPeople(data);
          }
        )
    }, []);

    return (
      <div className="App">
        <Character character={character} />
      </div>
    )
}

Upvotes: 0

AngelSalazar
AngelSalazar

Reputation: 3113

1) You should move your request calls to the componentDidMount lifecycle method

2) setState method is async, so logging the value may not give the correct value at that exact moment. To get the correct value of property, use the second argument (a function) that will called once the state is updated.

class App extends Component {
  constructor() {
    super()
    this.state = {
      people : [], // it should an array
      character: {}
    }
  }

  componentDidMount() {
    fetch("https://swapi.co/api/people/1")
            .then(response => response.json())
            .then(data => {
                this.setState({
                    character: data
                }, () => console.log(this.state.character))

            })

    fetch("https://swapi.co/api/people/")
            .then(response => response.json())
            .then(data => {
                this.setState({
                    people: data.results
                }, () => console.log(this.state.people.results))

            })

  }

  render() {
    return (
      <div className="App">
        <Character
          character = { this.state.character}
        />
      </div>
    );
  }
}

export default App;

Upvotes: 3

Related Questions