-3

As my first real MERN project, I'm building a message board. I'm currently working on a node route to request the board names with their associated post count but I've hit an issue. Instead of getting the values that I need, I'm recieving info telling me there is a promise pending, which seems odd as I'm using async/await. Here's the function:

exports.postsPerBoard = async (req, res) => {
  try {
    const boards = await Board.find();

    const postCount = boards.map(async (boardI) => {
      const posts = await Post.find({ board: boardI.slug });
      return [boardI.slug, posts.length];
    });
    console.log(postCount);
    res.send(postCount);
  } catch (err) {
    console.error(err.message);
    res.status(500).send('server error');
  }
};

and here is the result of the console log:

[0] [
[0]   Promise { <pending> },
[0]   Promise { <pending> },
[0]   Promise { <pending> },
[0]   Promise { <pending> },
[0]   Promise { <pending> }
[0] ]
Arnav Thorat
  • 3,078
  • 3
  • 8
  • 33
harry young
  • 600
  • 1
  • 8
  • 24

1 Answers1

5
const postCount = boards.map(async (boardI) => {
  const posts = await Post.find({ board: boardI.slug });
  return [boardI.slug, posts.length];
});

Since this is an async function, it will return a promise. map calls the function for each element of the array, gets the promises they return, and creates a new array containing those promises.

If you would like to wait for that array of promises to each finish, use Promise.all to combine them into a single promise, and then await the result.

const promises = boards.map(async (boardI) => {
  const posts = await Post.find({ board: boardI.slug });
  return [boardI.slug, posts.length];
});
const postCount = await Promise.all(promises);
console.log(postCount);
Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • Brilliant! Thank you Nicholas – harry young Sep 16 '20 at 23:56
  • Why do I need to await them all, though? Didn't I already do that inside the map function? (Thank you, it's working!) – harry young Sep 17 '20 at 00:04
  • Async functions return promises, and they do so synchronously. `map` doesn't check types: whatever is returned, that's what goes into the new array. So since promises are returned, promises go in the array. As for the `await` inside the function, that will delay when the returned promise resolves, but doesn't change the fact that a promise was (past tense) returned. – Nicholas Tower Sep 17 '20 at 00:41