Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose TypeError on a model's findOne method

The following TypeError cropped up in some old code.

TypeError: Object #<Object> has no method 'findOne'

The Model that was affected recently had two new static methods defined and those methods referenced external models. After backing out the new static methods, I was able to determine the root cause to be the require statements of the external models. The pattern looks like the following:

var UserModel = require('./user');

var GroupSchema = new Schema({
    name: String,
    users: [{ type : Schema.ObjectId, ref: 'UserModel'}],
});

GroupSchema.statics.findSomeUsers = function(group, callback) {
    this.find({name : session_user._id}, function(err, groups) {
        UserModel.find({_id : {$in : group.users}}, function(err,patients) {
            // do magic
        });
    });
};

module.exports = mongoose.model('GroupModel', GroupSchema);

There is a code fragment in the application that calls GroupModel.findOne({name:'gogo'}) that leads to the TypeError. when I remove the require statement for the UserModel in the GroupSchema, app code works again.

Why does Javascript start to think findOne() is an instance method with the addition of the require statement?

like image 662
Greg Avatar asked Jan 13 '13 20:01

Greg


1 Answers

It's known node.js issue. It means that you have looping require somewhere in your code and node.js forbids it.

The right way to do it is by using mongoose.model method. So, instead of UserModel variable you shall use mongoose.model('UserModel'). So, when findSomeUsers will be called mondoose will fetch UserModel and invoke its find method.

GroupSchema.statics.findSomeUsers = function(group, callback) {
    this.find({name : session_user._id}, function(err, groups) {
        mongoose.model('UserModel').find({_id : {$in : group.users}}, function(err,patients) {
            // do magic
        });
    });
};
like image 187
Leonid Beschastny Avatar answered Oct 16 '22 06:10

Leonid Beschastny