Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass a populated Mongoose object to the rendering code?

In the following code from my routes.js file, I can successfully populate some refs in a Mongoose object called Map. When I view the page, the console prints the fully populated version of popmap's editor objects.

  app.get('/map/:id', function(req, res){
    Map
    .findOne({ _id: req.map._id })
    .populate('_editors')
    .run(function (err, popmap) {
      console.log('The editors are %s', popmap._editors);
    });
    res.render('maps/show', {
      title: req.map.title,
      map: req.map
    });
  });

I have not figured out, though, how to perform the population step such that the resulting object remains in scope for the rendering code. In other words, how can I pass the populated object to the Jade template instead of just sending req.map?

like image 622
MW Frost Avatar asked Jan 04 '12 06:01

MW Frost


2 Answers

The problem is you are writing the Mongoose code as if it was synchronous, but you need to call res.render inside the run callback function, because that's when the query gets executed. In your example, the render function would get called before the results are returned by the query.

Besides that, you can pass the popmap variable as a local variable to the view:

app.get('/map/:id', function(req, res){
  Map
  .findOne({ _id: req.map._id })
  .populate('_editors')
  .run(function (err, popmap) {
    console.log('The editors are %s', popmap._editors);
    res.render('maps/show', {
      title: req.map.title,
      map: req.map,
      popmap: popmap // you can access popmap in the view now
    });
  });
});
like image 66
alessioalex Avatar answered Nov 26 '22 02:11

alessioalex


Note that the populate task is asynchronous, when the task is done, the callback function will be called on the result. Before that, the populated map will not be available.

Therefore, what you need to do is to put the rendering step inside the callback function.

  app.get('/map/:id', function(req, res){
    Map
    .findOne({ _id: req.map._id })
    .populate('_editors')
    .run(function (err, popmap) {
      console.log('The editors are %s', popmap._editors);
      res.render('maps/show', {
        title: popmap.title,
        map: popmap
      });
    });
  });
like image 31
qiao Avatar answered Nov 26 '22 02:11

qiao