I have struggled with the mongoose.model.populate
function for hours now. I have even tried directly copying and pasting several solutions without luck.
I have a User model which is supposed to contain an array of 'Dilemmas' which he/she has created, but I have been unable to populate it.
Here are the models as well as the implementation of populate()
.
User.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create Schema
const UserSchema = new Schema({
username: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
dilemmas: [
{
type: Schema.Types.ObjectId,
ref: "Dilemma"
}
]
});
module.exports = User = mongoose.model("User", UserSchema, "users");
Dilemma.js
const mongoose = require("mongoose");
const slug = require("mongoose-slug-generator");
const Schema = mongoose.Schema;
mongoose.plugin(slug);
// Create Schema
const DilemmaSchema = new Schema({
creator: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
title: {
type: String
},
slug: {
type: String,
slug: "title"
},
red: {
type: String,
required: true
},
blue: {
type: String,
required: true
},
red_votes: {
type: Number,
default: 0,
required: true
},
blue_votes: {
type: Number,
default: 0,
required: true
},
likes: [
{
user: {
type: Schema.Types.ObjectId,
ref: "User"
}
}
],
ments: [
{
user: {
type: Schema.Types.ObjectId,
ref: "User"
},
text: {
type: String,
required: true
},
author: {
type: String
},
avatar: {
type: String
},
date: {
type: Date,
default: Date.now
}
}
],
date: {
type: Date,
default: Date.now
}
});
module.exports = Dilemma = mongoose.model("Dilemma", DilemmaSchema, "dilemmas");
Routes.js
// @route GET api/users/profile
// @desc Gets logged in user's profile
// @access Private
router.get(
"/profile",
passport.authenticate("jwt", { session: false }),
(req, res) => {
User.find({ username: req.user.username })
.populate("dilemmas")
.then(user => {
if (!user) {
errors.nouser = "There is no user";
return res.status(404).json(errors);
}
res.json(user);
})
.catch(err => res.status(400).json(err));
}
);
JSON Response
[
{
"_id": "5b807beef770e7c7e6bf7ce0",
"dilemmas": [],
"username": "Jonas",
"email": "[email protected]",
"password": "$2a$10$QaqljS9x08YQ9N9EuCBTpO114ZJUFuVxAV80xMzImNi8eW2frPg0C",
"date": "2018-08-24T21:43:10.411Z",
"__v": 0
}
]
JSON Dilemmas response
[
{
"red_votes": 0,
"blue_votes": 0,
"_id": "5b80975f6e47fecba621f295",
"user": "5b807beef770e7c7e6bf7ce0",
"title": "Am i the real author asdsdasd?",
"red": "This is the red dilemma",
"blue": "This is the blue dilemma",
"likes": [],
"ments": [],
"date": "2018-08-24T23:40:15.381Z",
"slug": "am-i-the-real-author-asdsdasd",
"__v": 0
},
{
"red_votes": 0,
"blue_votes": 0,
"_id": "5b808e789bc36bcae8c6c3ad",
"creator": "5b807beef770e7c7e6bf7ce0",
"title": "Am i the real author?",
"red": "This is the red dilemma",
"blue": "This is the blue dilemma",
"likes": [],
"ments": [],
"date": "2018-08-24T23:02:16.565Z",
"slug": "am-i-the-real-author",
"__v": 0
}
]
JSON Users response
{
"_id": {
"$oid": "5b807beef770e7c7e6bf7ce0"
},
"dilemmas": [],
"username": "Jonas",
"email": "[email protected]",
"password": "$2a$10$QaqljS9x08YQ9N9EuCBTpO114ZJUFuVxAV80xMzImNi8eW2frPg0C",
"date": {
"$date": "2018-08-24T21:43:10.411Z"
},
"__v": 0
}
I have struggled with the mongoose.model.populate
function for hours now. I have even tried directly copying and pasting several solutions without luck.
I have a User model which is supposed to contain an array of 'Dilemmas' which he/she has created, but I have been unable to populate it.
Here are the models as well as the implementation of populate()
.
User.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create Schema
const UserSchema = new Schema({
username: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
dilemmas: [
{
type: Schema.Types.ObjectId,
ref: "Dilemma"
}
]
});
module.exports = User = mongoose.model("User", UserSchema, "users");
Dilemma.js
const mongoose = require("mongoose");
const slug = require("mongoose-slug-generator");
const Schema = mongoose.Schema;
mongoose.plugin(slug);
// Create Schema
const DilemmaSchema = new Schema({
creator: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
title: {
type: String
},
slug: {
type: String,
slug: "title"
},
red: {
type: String,
required: true
},
blue: {
type: String,
required: true
},
red_votes: {
type: Number,
default: 0,
required: true
},
blue_votes: {
type: Number,
default: 0,
required: true
},
likes: [
{
user: {
type: Schema.Types.ObjectId,
ref: "User"
}
}
],
ments: [
{
user: {
type: Schema.Types.ObjectId,
ref: "User"
},
text: {
type: String,
required: true
},
author: {
type: String
},
avatar: {
type: String
},
date: {
type: Date,
default: Date.now
}
}
],
date: {
type: Date,
default: Date.now
}
});
module.exports = Dilemma = mongoose.model("Dilemma", DilemmaSchema, "dilemmas");
Routes.js
// @route GET api/users/profile
// @desc Gets logged in user's profile
// @access Private
router.get(
"/profile",
passport.authenticate("jwt", { session: false }),
(req, res) => {
User.find({ username: req.user.username })
.populate("dilemmas")
.then(user => {
if (!user) {
errors.nouser = "There is no user";
return res.status(404).json(errors);
}
res.json(user);
})
.catch(err => res.status(400).json(err));
}
);
JSON Response
[
{
"_id": "5b807beef770e7c7e6bf7ce0",
"dilemmas": [],
"username": "Jonas",
"email": "[email protected]",
"password": "$2a$10$QaqljS9x08YQ9N9EuCBTpO114ZJUFuVxAV80xMzImNi8eW2frPg0C",
"date": "2018-08-24T21:43:10.411Z",
"__v": 0
}
]
JSON Dilemmas response
[
{
"red_votes": 0,
"blue_votes": 0,
"_id": "5b80975f6e47fecba621f295",
"user": "5b807beef770e7c7e6bf7ce0",
"title": "Am i the real author asdsdasd?",
"red": "This is the red dilemma",
"blue": "This is the blue dilemma",
"likes": [],
"ments": [],
"date": "2018-08-24T23:40:15.381Z",
"slug": "am-i-the-real-author-asdsdasd",
"__v": 0
},
{
"red_votes": 0,
"blue_votes": 0,
"_id": "5b808e789bc36bcae8c6c3ad",
"creator": "5b807beef770e7c7e6bf7ce0",
"title": "Am i the real author?",
"red": "This is the red dilemma",
"blue": "This is the blue dilemma",
"likes": [],
"ments": [],
"date": "2018-08-24T23:02:16.565Z",
"slug": "am-i-the-real-author",
"__v": 0
}
]
JSON Users response
{
"_id": {
"$oid": "5b807beef770e7c7e6bf7ce0"
},
"dilemmas": [],
"username": "Jonas",
"email": "[email protected]",
"password": "$2a$10$QaqljS9x08YQ9N9EuCBTpO114ZJUFuVxAV80xMzImNi8eW2frPg0C",
"date": {
"$date": "2018-08-24T21:43:10.411Z"
},
"__v": 0
}
Share
Improve this question
edited Aug 27, 2018 at 19:24
Jonas Mohr Pedersen
asked Aug 24, 2018 at 23:22
Jonas Mohr PedersenJonas Mohr Pedersen
5551 gold badge9 silver badges20 bronze badges
7
- could you post your sample collections for both the documents – Ashh Commented Aug 25, 2018 at 4:18
- populate({path:"path",model:"model"}) – Suhayb Commented Aug 27, 2018 at 16:18
- @AnthonyWinzlet, i have updated with the collections. – Jonas Mohr Pedersen Commented Aug 27, 2018 at 19:25
- Can you try rendering the dilemmas in your View? I believe there is a known issue with populate() that the data does not show in the JSON although you can display it in a view. – dikuw Commented Aug 27, 2018 at 19:30
- @Michael, I guess I can try. I haven't created the view yet though, but I will let you know once i am done. – Jonas Mohr Pedersen Commented Aug 27, 2018 at 19:31
3 Answers
Reset to default 8I just encountered a similar issue myself. Populating a ref worked, but populating an array of refs did not. I was able to get the array populate to work by explicitly specifying the model name in the populate call, e.g.:
User.find({ ... }).populate({
path: 'dilemmas',
model: 'Dilemma',
});
I don't know why this makes a difference, when the name of the referenced model is already specified in the schema.
Have you tried this?
User.find({ username: req.user.username })
.populate("dilemmas")
.exec() // <-- add exec() to perform the search
.then(user => {
...
})
Did you check the documentation here?
https://mongoosejs./docs/populate.html#refs-to-children
It shows a similar setup (with Authors and Stories.) It mentions 'pushing' stories to be able to use a find
/ populate
bo.