7

I am facing an issue where mongoose query is not populating an array type.

Here is institute schema

'use strict';

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var InstituteSchema = new Schema({
    name: String,
    address: String,
    city: String,
    country: String,
    zip: String,
    owner: { type: mongoose.Schema.ObjectId, ref: 'User' },
    teachers: [{type: mongoose.Schema.ObjectId, ref: 'Teacher'}],
    categories: [String],
    created : { type : Date, default : Date.now }
});

module.exports = mongoose.model('Institute', InstituteSchema);

And here is teacher Schema

'use strict';

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var TeacherSchema = new Schema({
    education: [{degree: String, instituteName: String}],
    dob: Date,
    photoUrl: String,
    phoneNumber: String,
    owner: {type: mongoose.Schema.ObjectId, ref: 'User'},
    institutes: [{type: mongoose.Schema.ObjectId, ref: 'Institute'}],
    subjects: [{type: mongoose.Schema.ObjectId, ref: 'Subject'}],
    created : { type : Date, default : Date.now }
})

module.exports = mongoose.model('Teacher', TeacherSchema);

Here is a method which queries the institute by owner id

exports.mine = function (req, res, next) {
    var ObjectId = mongoose.Types.ObjectId;
    var userId = new ObjectId(req.user._id);
    Institute.find({
        owner: userId
    }).populate('teachers').exec(function (err, institute) {
        if (err) return next(err);
        if (!institute) return res.json(401);
        res.json(institute);
    });
};

I can see from the db that institute has teacher added

db.institutes.find();
{ 
    "_id" : ObjectId("554719a9f5be11c6d4369264"), 
    "owner" : ObjectId("5547199bf5be11c6d4369263"), 
    "country" : "USA", 
    "name" : "Raghvendra Singh", 
    "address" : "38589 Royal Ann Cmn", 
    "city" : "Fremont", 
    "zip" : "94536", 
    "created" : ISODate("2015-05-04T07:03:05.569Z"), 
    "categories" : [ "IIT", "Medical" ], 
    "teachers" : [ ObjectId("55471965f5be11c6d436925f") ], 
    "__v" : 3 
}

But somehow the query method doesn't populate the teachers collection. The weird thing is that i don't even get the collection with object ids and it returns and institute with empty teacher array.

And when i remove the .populate('teachers') from the method call it indeed returns the teacher array with object ids.

I looked at the documentation and i can't see what am i doing wrong.

Raghvendra Singh
  • 1,775
  • 4
  • 26
  • 53
  • The `Teachers` file needs to be loaded at least once, before you call the `mine` function, to register the model with Mongoose. Are you loading that module somewhere before you call that function? – Brian Shamblen May 04 '15 at 16:05
  • I have "var Teacher = require('../teacher/teacher.model.js');" in the beginning of the file which has the mine function. @BrianShamblen is that what you meant? – Raghvendra Singh May 04 '15 at 18:33
  • Yes... Everything *looks* correct. The only other thing I would check is to verify the ObjectIds that are stored in the `teachers` array actually reference valid values in the teachers collection. Other than that, I don't see anything obvious. – Brian Shamblen May 04 '15 at 18:44
  • What does `db.teachers.find( { _id: ObjectId("55471965f5be11c6d436925f") } );` return ? – Aure77 Jun 03 '15 at 15:12
  • you have Institutes again under Teachers... Could it maybe be a problem with a circle reference?? did you checked your logs¿? – Alejandro Teixeira Muñoz Jun 08 '15 at 17:06
  • facing same issue. anybody found anything yet? – Shreejibawa Oct 12 '16 at 11:12
  • I got same issue resolved by renaming model: check more details here: http://stackoverflow.com/questions/40012717/mongoose-populate-not-working-with-array-of-objectids/40013856#40013856 – Shreejibawa Oct 13 '16 at 07:17
  • I am also facing this issue. – Amit Kumar Aug 07 '18 at 10:43

1 Answers1

4

First you need to change your Model slightly as mention for teachers feild.

teachers: [ { teacher: { type: Schema.ObjectId, ref: "Teacher" } } ]

exports.mine = function (req, res, next) {
    var ObjectId = mongoose.Types.ObjectId;
    var userId = new ObjectId(req.user._id);
    Institute.find({
        owner: userId
    }).populate('**teachers.teacher**').exec(function (err, institute) {
        if (err) return next(err);
        if (!institute) return res.json(401);
        res.json(institute);
    });
};

Then, change your populate parameter to teachers.teacher . It will work

Shishir Sonekar
  • 410
  • 1
  • 3
  • 15