0

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?

1
  • You must place the console.log () in an asynchronous function Commented Feb 14, 2019 at 23:41

2 Answers 2

3

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;
Sign up to request clarification or add additional context in comments.

Comments

0

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>
    )
}

2 Comments

JFYI: Hooks only works for functional components and only with React >=16.7
The information was not for you but for everyone else reading your answer. hooks were stable in 16.8 but implemented in 16.7 behind a feature flag.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.