1

I am doing a React.js project. I am trying to pull data from an API that has multiple endpoints. I am having issues with creating a function that pulls all the data at once without having to do every endpoint separetly. The console.log gives an empty array and nothing gets display. The props 'films' is data from the parent and works fine. It is also from another enpoint of the same API. This is the code:

import { useEffect, useState } from "react";

import styles from './MovieDetail.module.css';

const MovieDetail = ({films}) => {
    const [results, setResults] = useState([]);

    const fetchApis = async () => {
        const peopleApiCall = await fetch('https://www.swapi.tech/api/people/');
        const planetsApiCall = await fetch('https://www.swapi.tech/api/planets/');
        const starshipsApiCall = await fetch('https://www.swapi.tech/api/starships/');
        const vehicleApiCall = await fetch('https://www.swapi.tech/api/vehicles/');
        const speciesApiCall = await fetch('https://www.swapi.tech/api/species/');
        const json = await [peopleApiCall, planetsApiCall, starshipsApiCall, vehicleApiCall, speciesApiCall].json();
        setResults(json.results)        
    }

    useEffect(() => {
            fetchApis();
    }, [])

    console.log('results of fetchApis', results)

    return (
        <div className={styles.card}>
            <div className={styles.container}>
                <h1>{films.properties.title}</h1>
                <h2>{results.people.name}</h2>
                <p>{results.planets.name}</p>
            </div>            
        </div>
    );
}
 
export default MovieDetail;

UPDATE

I just added the post of Phil to the code and I uploaded to a codesanbox

2
  • Not able to call the APIs, too many requests error HTTP 429. Commented Dec 21, 2021 at 6:45
  • 1
    I've seen the error @kiner_shah I am trying to solve it. Thanks. Commented Dec 21, 2021 at 9:42

1 Answer 1

3

You want to fetch and then retrieve the JSON stream from each request.

Something like this

const urls = {
  people: "https://www.swapi.tech/api/people/",
  planets: "https://www.swapi.tech/api/planets/",
  starships: "https://www.swapi.tech/api/starships/",
  vehicles: "https://www.swapi.tech/api/vehicles/",
  species: "https://www.swapi.tech/api/species/"
}

// ...

const [results, setResults] = useState({});

const fetchApis = async () => {
  try {
    const responses = await Promise.all(Object.entries(urls).map(async ([ key, url ]) => {
      const res = await fetch(url)
      return [ key, (await res.json()).results ]
    }))

     return Object.fromEntries(responses)
  } catch (err) {
    console.error(err)
  }
}

useEffect(() => {
  fetchApis().then(setResults)
}, [])

Each URL will resolve to an array like...

[ "people", [{ uid: ... }] ]

Once all these resolve, they will become an object (via Object.fromEntries()) like

{
  people: [{uid: ... }],
  planets: [ ... ],
  // ...
}

Take note that each property is an array so you'd need something like

<h2>{results.people[0].name}</h2>

or a loop.

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

3 Comments

Thanks Phil for the help. Unfortunately, it givs an empty array if I do a console.log of results and also, nothing gets display in the return
@JoaquinPalacios looks like /vehicle is a wrong URL. It should it be /vehicles. I've updated my answer
@JoaquinPalacios you seem to have gone in an odd direction in your sandbox link so I've updated my answer to be clearer.

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.