简体   繁体   中英

Setting Bookshelf attribute during initialization throws an error on 'this' being undefined

I'm seeing weird behavior regarding 'this' in a Bookshelf model and am stumped. I'm attempting to hash a password using a hook on the 'saving' event. However, if I try and get/set an attribute on 'this', it complains 'this' is undefined:

'use strict';

var DB = require('../config/db'),
    _ = require('underscore'),
    str = require('underscore.string'),
    Base = require('./base'),
    Promise = require('bluebird'),
    bcrypt = Promise.promisifyAll(require('bcrypt'));

var User = DB.Model.extend({
  tableName: 'users',
  hasTimestamps: ['createdAt', 'updatedAt'],

   // convert snake_case to camelCase
  parse: function(attrs) {
    return _.reduce(attrs, function(memo, val, key) {
      memo[str.camelize(key)] = val;
      return memo;
    }, {});
  },

  // convert camelCase to snake_case
  format: function(attrs) {
    return _.reduce(attrs, function(memo, val, key) {
      memo[str.underscored(key)] = val;
      return memo;
    }, {})
  },

  initialize: function() {
    this.on('saving', this.hashPassword, this);
  },

  hashPassword: function() {
    return bcrypt.genSaltAsync(10).then(function(salt){
      return bcrypt.hashAsync(this.get('password'), salt);
    }).then(function(hash){
      this.set({'password':hash});
    });
  }
});

module.exports = User;

When I try and save a user model, I'm seeing the following stack trace:

Debug: internal, implementation, error 
    Error: TypeError: Cannot call method 'get' of undefined
    at Object.exports.create (/usr/src/app/node_modules/boom/lib/index.js:21:17)
    at Object.exports.internal (/usr/src/app/node_modules/boom/lib/index.js:254:92)
    at Object.exports.badImplementation (/usr/src/app/node_modules/boom/lib/index.js:290:23)
    at null.<anonymous> (/usr/src/app/routes/users.js:31:20)
    at tryCatcher (/usr/src/app/node_modules/bluebird/js/main/util.js:24:31)
    at Promise._settlePromiseFromHandler (/usr/src/app/node_modules/bluebird/js/main/promise.js:454:31)
    at Promise._settlePromiseAt (/usr/src/app/node_modules/bluebird/js/main/promise.js:530:18)
    at Promise._settlePromises (/usr/src/app/node_modules/bluebird/js/main/promise.js:646:14)
    at Async._drainQueue (/usr/src/app/node_modules/bluebird/js/main/async.js:177:16)
    at Async._drainQueues (/usr/src/app/node_modules/bluebird/js/main/async.js:187:10)
    at Async.drainQueues (/usr/src/app/node_modules/bluebird/js/main/async.js:15:14)
    at process._tickDomainCallback (node.js:486:13)

Any ideas?

Does this work?

hashPassword: function() {

    var self = this;

    return bcrypt.genSaltAsync(10).then(function(salt) {
        return bcrypt.hashAsync(self.get('password'), salt);
    }).then(function(hash) {

        self.set({
            'password': hash
        });

    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM