Trouble with promises in mongoose

Hi campers,

What I am trying to do:
Get all forum threads (an array of objects), then for each thread get the user associated with it and assign the user’s name to the thread. The thread objects have a user ID based on what user created the thread. The user objects (found separately) have user names. I want to do this because if the user changes their name, all threads will reflect that change.

The problem is that the response is sending the threads before they are updated with the user name. I think it is because the findById promises are not resolving before the response triggers. I tried wrapping it in my own self-made promise, but it still has the issue.

Do you know any way to make it wait for the User.findById promises to complete before sending?

// @desc    Get all threads in section
// @route   GET api/:forumSection/
// @access  PUBLIC
router.get("/:forumSection", (req, res) => {
  Thread.find({ forumSection: req.params.forumSection })
    .sort({ date: -1 })
    .then(threads => {
      return new Promise((resolve, reject) => {
        for (thread of threads) {
          User.findById(thread.user).then(user => {
            thread.userName = user.name;
            console.log(thread.title);
          });
        }
        resolve();
      }).then(res.json(threads);
    })
    .catch(err => res.status(404).json({ nothreadfound: "No thread found" }));
});

I’m guessing a bit but should
User.findById return something?

It is returning the user object from which I obtain the user name. That part is working, but the problem is it executes after I already returned the threads.

Personally I would run that code through a debugger. To read the code and figure out what is going on is beyond me.

After a long time searching, I found this answer: (I put the user’s name as the thread title just for testing purposes. Now I will change it to the thread’s user name)

Found the answer in this thread: https://stackoverflow.com/questions/39452083/using-promise-function-inside-javascript-array-map

router.get("/:forumSection", (req, res) => {
  Thread.find({ forumSection: req.params.forumSection })
    .sort({ date: -1 })
    .then(threads => {
      let promises = threads.map(thread => {
        return User.findById(thread.user).then(user => {
          thread.title = user.name;
          return thread;
        });
      });
      Promise.all(promises).then(threads => {
        res.json(threads);
      });
    })
    .catch(err => res.status(404).json({ nothreadfound: "No thread found" }));
});
1 Like