Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose method undefined

I'm trying to create a 'checkPassword' method for my User model, however whenever I call it I get the following error:

User.checkPassword(password, hash, function(err, samePassword){
             ^
TypeError: undefined is not a function

I'm pretty new to mongoose so I'm not sure where I'm going wrong.

users.js (User model)

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


var userSchema = new Schema({
 email : {type: String, required: true, unique: true},
 password : {type: String, required: true},
 firstName : {type: String},
 lastName : {type: String}
});


userSchema.methods.checkPassword = function checkPassword(password, hash, done){

    bcrypt.compare(password, hash, function(err, samePassword) {
      if(samePassword === true){
        done(null, true);
      } else {
        done(null, false)
      }
    });
}

module.exports = mongoose.model('User', userSchema);

passport.js

var passport = require('passport'),
    LocalStrategy = require('passport-local').Strategy,
    mongoose = require('mongoose'),
    usersModel = require('../models/users'),
    User = mongoose.model('User');


passport.use(new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password'
  }, function(email, password, done){

    User.findOne({'email': email}, function(err, user){
      if(user){

        var hash = user.password;
        User.checkPassword(password, hash, function(err, samePassword){
          if(samePassword === true){
            done(null, user);
          }

etc..

If I console.log the User model (at the start of passport.js), I can see that the method is there, but I'm unable to use it. My model layout is similar to the one in the documentation: http://mongoosejs.com/docs/guide.html (Instance methods section).

like image 675
Ash Avatar asked Dec 20 '22 03:12

Ash


1 Answers

You're declaring an instance method (meant to be called on instances of the User model/class) but you're calling it as a class method (a static method in Mongoose parlance).

Here's a small demonstration:

var mongoose   = require('mongoose');
var testSchema = new mongoose.Schema({ test : String });

testSchema.methods.myFunc = function() {
  console.log('test!');
};

var Test = mongoose.model('Test', testSchema);

// This will fail, because you're calling a class method.
Test.myFunc();

// This will work, because you're calling the method on an instance.
var test = new Test();
test.myFunc();

So in your code, you should either replace User.checkPassword(...) by user.checkPassword(...) (and rewrite it a bit), or make it a proper class method by using userSchema.statics.checkPassword = function(...).

like image 62
robertklep Avatar answered Dec 21 '22 17:12

robertklep