How do I pass a populated Mongoose object to the rendering code?
Problem
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
?
Solution
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
});
});
});
Discussion
View additional discussion.