0

I have an array of ids and I am trying to map through this array to create a new array of movie objects which is in my database.

my code looks like this...

const movieIds = foundDirector.movies;

const movies = movieIds.map(async (id) => {
    await Movie.findById(id);
  });

The code above doesn't work. I am able to find a movie and see that data from within the map function but when I print movies to the console I get an array with empty objects.

I then decided to do this instead and it works.

const movieIds = foundDirector.movies;
let movies = [];

for (let i = 0; i < movieIds.length; i++) {
  const movie = await Movie.findById(movieIds[i]);
  movies.push(movie);
}

I'm not happy with the solution. I obviously am having issues understanding how promises work in JavaScript and using async/await has been easy enough for now but I don't want to rely on it.

as an example I tried doing something like...

const movieIds = foundDirector.movies;
let movies = [];

for (let i = 0; i < movieIds.length; i++) {
  const movie = Movie.findById(movieIds[i]).then((data) => data);
  movies.push(movie);
}

const allMovies = Promise.all(movies).then((values) => values);

I noticed that after printing movies to the console I was getting an array of pending promises I tried using const allMovies = Promise.all(movies).then((values) => values); but allMovies still just is a pending promise.

Can anyone please explain what is going on here, and how can I achieve this with a map function rather than a for loop.

Michael Torres
  • 512
  • 3
  • 21
  • 1
    What about `const allMovies = await Promise.all(movieIds.map(Movie.findById))` – Eldar May 15 '20 at 09:04
  • 1
    I think you can find your response [Use async await with Array.map](https://stackoverflow.com/a/40140562/13212908) – Andre LECLERCQ May 15 '20 at 09:15
  • Yes that works, of course it still is using await, so I guess from my understanding and further research, without using await I can only access the actual values within the `then`. Before looking at all the answers I ended up just doing `Promise.all(movies).then((data) => res.json(data))` to try to get it without await. Is this the reason why `async/await` was created. Quite honestly it is extremely annoying that without await we can't have a variable that holds these values without a pending promise. Await is cool and all but I just want to make sure I really understand this is how it works. – Michael Torres May 15 '20 at 09:55

1 Answers1

1

Well, you can achieve what you want with an approach like below.

const allMovies = await Promise.all(movieIds.map(Movie.findById))

It just maps ids to promises and awaits all of them.

const allMovies = Promise.all(movies).then((values) => values);
console.log(allMovies);

The above code will log awaiting promises because by the time that console.log nothing has happened yet. There is nothing that awaits those promises to have resulted. Then callback has no effect on allMovies variable. This answer has nice info about it.

Eldar
  • 9,781
  • 2
  • 10
  • 35