Using Instance Methods in Sequelize

23,566

Solution 1

Instance method can be used on specific element instances eg.

models.User.find(123).success( function( user ) { 
    user.setPassword('test');
});

Solution 2

You define the function as: function(password, done)

Yet you don't supply the done parameter. Thus, the function leaves done as undefined and calling done() is executing an undefined function.

You could fix this in 3 ways:

  1. Default done to a noop function function () {}
  2. Only return done() if done is defined
  3. Supply a done callback when calling the instance function.

The alternative is to refactor it to return a promise which it resolves on completion.

Share:
23,566

Related videos on Youtube

surfearth
Author by

surfearth

Updated on July 09, 2022

Comments

  • surfearth
    surfearth almost 2 years

    Can someone help me understand how to use instance methods in Sequelize? I've reviewed the documentation but have found it to be sparse. At present, I am trying to use setPassword and verifyPassword instance methods on my user model. When I try to call the code in the REPL, after having imported the user model and synced the DB, I get the following:

    > models.User.setPassword('test');
    TypeError: Object [object Object] has no method 'setPassword'
    

    Here is the code for the user model:

    var bcrypt = require('bcrypt');
    
    module.exports = function(sequelize, DataTypes) {
      return sequelize.define('User', {
        email: { type: DataTypes.STRING, unique: true, allowNull: false, validate: { isEmail: true } },
        password: { type: DataTypes.STRING, allowNull: false},
        firstName: {type: DataTypes.STRING},
        lastName: {type: DataTypes.STRING},
        companyName: {type: DataTypes.STRING},
        admin: {type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false,},
        forgotUrl: {type: DataTypes.STRING, unique: true},
        forgotDate: {type: DataTypes.STRING},
        lastLogin: {
          type: DataTypes.DATE,
          defaultValue: DataTypes.NOW
        }
      }, {
        paranoid: true,
        instanceMethods: {
          setPassword: function(password, done) {
            return bcrypt.genSalt(10, function(err, salt) {
              return bcrypt.hash(password, salt, function(error, encrypted) {
                this.password = encrypted;
                this.salt = salt;
                return done();
              });
            });
          },
          verifyPassword: function(password, done) {
            return bcrypt.compare(password, this.password, function(err, res) {
              return done(err, res);
            });
          }
        }
      });
    };
    
    • Erik  Reppen
      Erik Reppen over 9 years
      Why the returns before all your callback calls?
    • Daniel C
      Daniel C over 8 years
      the use of this in the setPassword instance method will fail to refer to the actual User instance.
  • surfearth
    surfearth over 10 years
    Ahh, that makes perfect sense. Do you have any idea why I am getting TypeError: undefined is not a function from return done() when I run: > models.User.find(1).success( function( user ) { user.setPassword('password'); });
  • SergeS
    SergeS over 10 years
    no idea . I'm using this construct in my project without a problem
  • Ryan White
    Ryan White over 8 years
    surfearth. "done" is the second parameter to setPassword, which has to be a function as you call it "return done();". You aren't passing in a parameter, so "done" is undefined and is not a function.