I hope someone can help me with this issue. I am trying to populate a subSchema but I have no luck.
I have a replySchema
, commentSchema
and a UserSchema
.
replySchema
is subDocument to commentSchema
and I want to populate both of them with user's details from userSchema
My issue is that with the code below it does not populate my replySchema
:
REPLY-SCHEMA and COMMENT-SCHEMA
const replySchema = new mongoose.Schema(
{
replyComment: {
type: String,
required: [true, 'Reply comment cannot be empty'],
},
createdAt: {
type: Date,
default: Date.now(),
},
user: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: [true, 'Comment must belong to a user'],
},
},
{
timestamps: true,
}
);
const commentSchema = new mongoose.Schema(
{
comment: {
type: String,
required: [true, 'Comment cannot be empty'],
},
createdAt: {
type: Date,
default: Date.now(),
},
// createdAt: Number,
// updatedAt: Number,
post: {
type: mongoose.Schema.ObjectId,
ref: 'Post',
required: [true, 'Comment must belong to a Post'],
},
user: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: [true, 'Comment must belong to a user'],
},
replies: [replySchema], //replySchema sub-document - is this the right way?
},
{
// timestamps: { currentTime: () => Math.floor(Date.now() / 1000) },
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
);
replySchema.pre(/^find/, function (next) {
this.populate({
path: 'user',
select: 'name role avatar',
});
next();
});
commentSchema.pre(/^find/, function (next) {
this.populate({
path: 'user',
select: 'name role avatar',
});
next();
});
const Comment = mongoose.model('Comment', commentSchema);
module.exports = Comment;
USER-SCHEMA
const userSchema = new mongoose.Schema(
{
name: {
type: String,
trim: true,
required: [true, 'Please insert your name'],
},
avatar: {
type: Object,
},
role: {
type: String,
enum: ['user', 'admin'],
default: 'user',
},
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
);
const User = mongoose.model('User', userSchema);
module.exports = User;
Thank you very much for your time!
To populate user's data in replies:
this.populate([
'user', // To populate commentSchema's user field
{
path: 'replies',
populate: 'user'
} // To populate replySchema's user field
]);
Edit:
To populate specific fields:
this.populate([
{
path: 'user',
select: 'name role avatar'
},
{
path: 'replies',
populate: {
path: 'user',
select: 'name role avatar'
}
}
]);