WonkasWilly
WonkasWilly

Reputation: 573

Promise.all returning empty objects

I'm trying to get multiple data objects from The Movie Database at once using Promise.all. After I loop through all the results of the fetch call, and use .json() on each bit of data, I tried to log it to the console. However, rather than an array of objects with data, I'm getting an array of Promises. Nested in the promises, I can see my data, but I'm clearly missing a step in order to have an array of data objects, instead of just Promises.

What am I missing here?

 //store movie API URLs into meaningful variables
    const trending = `https://api.themoviedb.org/3/trending/all/day?api_key=${API_KEY}`;
    const topRated = `https://api.themoviedb.org/3/movie/top_rated?api_key=${API_KEY}&language=en-US&page=1`;
    const nowPlaying = `https://api.themoviedb.org/3/movie/now_playing?api_key=${API_KEY}&language=en-US&page=1`;
    const upcoming = `https://api.themoviedb.org/3/movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`;
    //create an array of urls to fetch data from
    const allMovieURLs = [trending, topRated, nowPlaying, upcoming];
    const promiseURLs = allMovieURLs.map(url => fetch(url));
    Promise.all(promiseURLs)
      .then(responses => responses.map(url => url.json()))
      .then(dataArr => console.log(dataArr));
  };

Upvotes: 11

Views: 1889

Answers (2)

George.S
George.S

Reputation: 149

try doing it this way

const promiseURLs = allMovieURLs.map(url => fetch(url).then(res => res.json()));
Promise.all(promiseURLs)
  .then(responses => responses.forEach(response => { console.log(response)})

Upvotes: 4

CertainPerformance
CertainPerformance

Reputation: 370709

Your .then(responses => responses.map(url => url.json())) resolves to an array of Promises, so you need to call Promise.all again if you want to wait for all to resolve:

Promise.all(promiseURLs)
  .then(responses => Promise.all(responses.map(url => url.json())))
  .then(dataArr => console.log(dataArr));

Or, you might consider using just one Promise.all, and having each URL fetch and the json, that way some items aren't idle in the middle of script execution:

const allMovieURLs = [trending, topRated, nowPlaying, upcoming];
const promiseURLs = allMovieURLs.map(url => fetch(url).then(res => res.json()));
Promise.all(promiseURLs)
  .then(dataArr => console.log(dataArr));

Upvotes: 19

Related Questions