0

I'm a beginner in react and I have the following issues:

Im using an API that has more than 60 characters, my issue is that I want to make sure all the characters of my API render up without me having to manually add each number.({this.state.people[0].name}, ..., {this.state.people[n].name}).

This issue also made me do the API call two times because the API gives only 10 results per call. they next for page 2.

I created a new call with ?=page2 but this is a very tedious way of doing it because I would have to add 10 different API calls to add all the characters. I thought about doing a for loop but I dont really know how to approach this.

class Api extends Component {

state ={
    people:[
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    ],

    people2:[
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    {name:'Title'},
    ]
}

componentDidMount() {
  axios.get('https://swapi.co/api/people/')

  .then(starwars => {
    this.setState({
        people: starwars.data.results
    })
    console.log(starwars.data.results)

  })
axios.get('https://swapi.co/api/people/?page=2')
  .then(starwars2 => {
    this.setState({
        people2: starwars2.data.results
    })
    console.log(starwars2.data.results)

  })
  .catch(error => {
    console.log(error);
  });
}

  render(){
    return ( 

        <div>
        <Cards title={this.state.people[0].name} />
        <Cards title={this.state.people[1].name} />
        <Cards title={this.state.people[2].name} />
        <Cards title={this.state.people[3].name} />
        <Cards title={this.state.people[4].name} />
        <Cards title={this.state.people[5].name} />
        <Cards title={this.state.people[6].name} />
        <Cards title={this.state.people[7].name} />
        <Cards title={this.state.people[8].name} />
        <Cards title={this.state.people[9].name}  />
        <Cards title={this.state.people2[0].name}  />
        <Cards title={this.state.people2[1].name}  />
        <Cards title={this.state.people2[2].name}  />
        <Cards title={this.state.people2[3].name}  />
        <Cards title={this.state.people2[4].name}  />
        <Cards title={this.state.people2[5].name}  />
        <Cards title={this.state.people2[6].name}  />
        <Cards title={this.state.people2[7].name}  />
        <Cards title={this.state.people2[8].name}  />
        <Cards title={this.state.people2[9].name}  />

</div>)
  }
}
export default Api;


Make the API call for the 60 characters in one call.

Sundios
  • 418
  • 7
  • 20
  • [Looping inside JSX](https://stackoverflow.com/q/22876978/1218980) – Emile Bergeron Apr 08 '19 at 22:13
  • Your problem is with the API, not with axios. you need to read the API documentation and discover how to retrieve all the characters with a single request. – reisdev Apr 08 '19 at 22:15
  • I don't think I saw an option for getting all records. As you say, you could loop through and do as many requests as it it takes to get all **people**. The response shows a `count` that is currently `87`. You could do some division to figure out how many **pages** or requests you need to do. – go_diego Apr 08 '19 at 22:43

1 Answers1

3

As you said, you could loop through programmatically and get all people. To do this you would need to know how many pages are there. Requesting to https://swapi.co/api/people/ returns a count as part of the response. Assuming that's the count of total people, you can use it to calculate the number of pages you need to query. It would look something like this:

Note: I used Node for this, just add the necessary React bits.

const axios = require("axios");
// first page
axios("https://swapi.co/api/people/")
    .then(starwars => {
        return starwars.data.count;
    })
    .then(count => {
        // exclude the first request
        const numberOfPagesLeft = Math.ceil((count - 1) / 10);
        let promises = [];
        // start at 2 as you already queried the first page
        for (let i = 2; i <= numberOfPagesLeft; i++) {
            promises.push(axios(`https://swapi.co/api/people?page=${i}`));
        }
        return Promise.all(promises);
    })
    .then(response => {
        // collect all results into one array
        const result = response.reduce((acc, data) => [...acc, ...data.data.results], []);
        return result;
        //result should contain the remaining records - pages 2 through n.
    })
    .catch(error => console.log("Properly handle your exception here"));

As always, be aware of the fast-fail behavior of Promise.all

go_diego
  • 393
  • 2
  • 7
  • For completeness, I should mention that I didn't store the `results` from the first request so that your final result doesn't include the first 10 people. You could define a `persons` variable outside of the promise chains and use that variable to collect them all. – go_diego Apr 09 '19 at 15:04