0xef2387 0xef2387 - 1 month ago 8
Node.js Question

Need some clarification on mongoose/mongodb populate command

Hello so I am making a basic app with users and posts.

I followed the mongoose documentation on population (http://mongoosejs.com/docs/2.7.x/docs/populate.html) and setup my Schemas so that the users and be connected to posts

var userSchema = new mongoose.Schema({
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
email: String,
created_at: Date,
updated_at: Date,
admin: Boolean,
posts: [{ type: mongoose.Schema.ObjectId, ref: 'Post' }]
});

var postSchema = new mongoose.Schema({
_user : [{ type: mongoose.Schema.ObjectId, ref: 'User' }],
audioFile: { type: String, required: true },
imageFile: { type: String },
title: { type: String, required: true },
artist: { type: String, required: true },
start: { type: String, required: true },
stop: { type: String, required: true },
genre: { type: String, required: true },
tags: [{ type: String }]

});





app.get('/', function (req, res){
Post.find({}, function(err, allPosts){
if(!err){
res.render('main.njk', {
posts : allPosts,
title : 'Title',
isLogged : req.session.isLogged,
user : req.session.user,
messages : req.flash('alert')
});
} else { return done(err); }
});

});


Thats all fine and gravy and I can run a foreach loop on allPosts to pull each one in my HTML, but when I try to think of how I am going to display all the posts with their respective users attached to each post I am unsure of how to connect the two since all the examples in the mongoose doc is just mainly for findOne.

I was thinking something like this

app.get('/', function (req, res){
Post.find({}, function(err, allPosts){
if(!err){
allPosts.populate('_user', ['username']);
allPosts.exec(function (err, users){
if(err) console.log(err);
console.log(users);
});
res.render('main.njk', {
posts : allPosts,
title : 'Spaurk.net',
isLogged : req.session.isLogged,
user : req.session.user,
messages : req.flash('alert')
});
} else { return done(err); }
});

});


but that doesn't work of course.

So I was wondering if anyone with experience with this situation would be able to help me solve this.

Thanks a lot for any input.

EDIT, thanks to Daves help I was able to get the populate to work properly, I just cant pull the fields I want correctly with

Post.find({}).populate('_user').exec(function(err, allPosts){


In my loop {% for post in posts %}
, when I do post._user it shows the whole user schema, but when I do post._user.username it doesn't return anything. I am unsure as to why this is.

Answer

The proper way to structure a populate on a query is like this:

Post.find({})
    .populate('_user')
    .exec((err, allposts){...})

Then you will have an array of your Posts with the _user array populated. If you need to access a property of a user, you will need to do another loop through the _user array or specify with use you want to use _user[0].<property>