Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoose Model.findOne TypeError: Object has no method 'findOne'

Tags:

mongoose

I have a simple node.js code that uses mongoose which works when saving but doesn't retrieve.

.save() works, but .findOne() doesn't.

mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/TestMongoose");
UserSchema = new mongoose.Schema({
    field: String
    });
Users = mongoose.model('userauths', UserSchema);

user = new Users({
    field: 'value'
    });

//user.save();  

^ works. i.e. updates the database with values. screenshot


//user.findOne({field:'value'},function(err,value){});

^ Throws error:

user.findOne({field:'value'},function(err,value){});
     ^
TypeError: Object { field: 'value', _id: 52cd521ea34280f812000001 } has no method 'findOne'
    at Object.<anonymous> (C:\localhost\nodeTest\z.js:16:6)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3

console.log(JSON.stringify(   user    , null, 40));

^ returns just the object {field: 'value'}

console.log(JSON.stringify(   Users   , null, 40));

^ returns undefined

Users.findOne();

^ no error, but doesn't return anything.
(so does the function findOne() exists in Users? but so why then does console.log(..Users.. returns undefined?)

What could be the issue causing findOne() to not work as expected?

like image 230
laggingreflex Avatar asked Jan 08 '14 12:01

laggingreflex


2 Answers

findOne is a method on your Users model, not your user model instance. It provides its async results to the caller via callback:

Users.findOne({field:'value'}, function(err, doc) { ... });
like image 128
JohnnyHK Avatar answered Nov 17 '22 12:11

JohnnyHK


To elaborate on the current answer which is correct, notice the difference between userSchema.path and userSchema.statics - the former uses 'this' as the instance of the model, while in the latter 'this' refers to the model "class" itself:

       var userSchema = ...mongoose schema...;

       var getUserModel = function () {
            return mongoDB.model('users', userSchema);
        };


       userSchema.path('email').validate(function (value, cb) {
                getUserModel().findOne({email: value}, function (err, user) {
                    if (err) {
                        cb(err);
                    }
                    else if(user){  //we found a user in the DB already, so this email has already been registered
                        cb(null,false);
                    }
                    else{
                        cb(null,true)
                    }
                });
            },'This email address is already taken!');


     userSchema.statics.findByEmailAndPassword = function (email, password, cb) {
                this.findOne({email: email}, function (err, user) {
                    if (err) {
                        return cb(err);
                    }
                    else if (!user) {
                        return cb();
                    }
                    else {
                        bcrypt.compare(password, user.passwordHash, function (err, res) {
                            return cb(err, res ? user : null);
                        });
                    }

                });

            };

        };
like image 36
Alexander Mills Avatar answered Nov 17 '22 13:11

Alexander Mills