Kevin Guevara
Kevin Guevara

Reputation: 65

node js express populate

found this piece of code that is not so straight forward and was wondering if someone could help me clear up what the method is doing.

// return an article's comments
router.get('/:article/comments', auth.optional, function(req, res, next){
  Promise.resolve(req.payload ? User.findById(req.payload.id) : null).then(function(user){
    return req.article.populate({
      path: 'comments',
      populate: {
        path: 'author'
      },
      options: {
        sort: {
          createdAt: 'desc'
        }
      }
    }).execPopulate().then(function(article) {
      return res.json({comments: req.article.comments.map(function(comment){
        return comment.toJSONFor(user);
      })});

    });
  }).catch(next);
});

from my initial reading of the method we are:

  1. checking our payload and if its not null, we finding the user else return null
  2. then we pass the user to our function(user) method and return req.article.populate(). i am not entirely sure why we need the {path: 'comments', populate:{ path: ..}..} section
  3. then we execPopulate().then and return the json doc

Im mostly confused as to why we need to set up the path on the first populate when we are doing execPopulate at the bottom

Upvotes: 0

Views: 650

Answers (1)

Cisco
Cisco

Reputation: 23052

I've cleaned up the nested promises to use async-await to make it read more synchronous. You're on the right path, but I think this will help a lot:

async function handleRoute(req, res, next) {
    try {
        const id = req.payload ? req.payload.id : null
        const user = await User.findById(id).exec()

        if (!user) {
            throw new Error('User does not exist')
        }

        const populateOptions = {
            path: 'comments',
            populate: {
              path: 'author'
            },
            options: {
              sort: {
                createdAt: 'desc'
              }
            }
        }

        const article = await req.article.populate(populateOptions).execPopulate()
        const comments = article.comments.map(comment => comment.toJSONFor(user))

        res.json({ comments })
    } catch (error) {
        next(error)
    }
}

router.get('/:article/comments', auth.optional, handleRoute)

Upvotes: 1

Related Questions