Reputation: 357
I have defined a UserSchema
and a PostSchema
in my model.js. UserSchema
has a ref to its own Post
s, while PostSchema
has a ref to its author.
In my controllers.js
methods I'm creating a user and a post instance (bound to the newly created user). I'm now trying to populate the user's posts, but mongoose returns an empty array. However, the other way around works (I'm able to retrieve the user by a Post instance).
models.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
username: String,
posts: [{
type: Schema.Types.ObjectId,
ref: 'Post'
}]
})
const PostSchema = new Schema({
content: String,
author: {
type: Schema.Types.ObjectId,
ref: 'User'
}
})
const Post = mongoose.model('Post', PostSchema, 'posts');
const User = mongoose.model('User', UserSchema, 'users');
module.exports = { Post, User }
controllers.js
require('../model/db'); // DB config
const mongoose = require('mongoose');
const models = require('../model/models');
const getUser = (req, res) => {
const user = new models.User({
_id: new mongoose.Types.ObjectId(),
username: 'JohnDoe'
});
user.save(function (err) {
if (err) return res.json(err);
const post = new models.Post({
content: 'New Post',
author: user.id
});
post.save(function (err) {
if (err) return res.json(err);
models.User.findOne({
username: 'JohnDoe'
})
.populate('posts').exec((err, user) => {
res.json(user);
})
});
});
}
const getPost = (req, res) => {
const user = new models.User({
_id: new mongoose.Types.ObjectId(),
username: 'JohnDoe'
});
user.save(function (err, user) {
if (err) return res.json(err);
const post = new models.Post({
content: 'NewPost',
author: user.id
});
post.save(function (err, post) {
if (err) return res.json(err);
models.Post.findOne({
content: 'NewPost'
})
.populate({
path: 'author',
model: 'User'
}).exec((err, user) => {
res.json(user);
})
});
});
}
getUser
's result (posts is empty):
{
"posts": [],
"_id": "5b9426a6fd187d3949470f54",
"username": "JohnDoe",
"__v": 0
}
getPost
result (author is correctly returned)
{
"_id": "5b94287e99072c3a173419f2",
"content": "NewPost",
"author": {
"posts": [],
"_id": "5b94287e99072c3a173419f0",
"username": "JohnDoe",
"__v": 0
},
"__v": 0
}
Upvotes: 1
Views: 1045
Reputation: 103365
You need to push the post id to the posts array in the user model as follows
const getUser = (req, res) => {
const newUser = new models.User({ username: 'JohnDoe' });
newUser.save(user => {
if (err) return res.json(err);
const newPost = new models.Post({
content: 'New Post',
author: user._id
});
newPost.save(post => {
if (err) return res.json(err);
models.User.findByIdAndUpdate(user._id,
{ '$push': { 'posts': post._id } },
{ 'new': true }
)
.populate('posts')
.exec((err, u) => {
res.json(u);
})
});
});
}
Using async/await
const getUser = async (req, res) => {
try {
const newUser = new models.User({ username: 'JohnDoe' });
const user = await newUser.save();
const newPost = new models.Post({
content: 'New Post',
author: user._id
});
const post = await newPost.save();
const result = await models.User.findByIdAndUpdate(user._id,
{ '$push': { 'posts': post._id } },
{ 'new': true }
)
.populate('posts')
.exec();
res.json(result)
}
catch (err) {
return res.json(err);
}
}
Upvotes: 1