Does Mongoose pre save use the wrong "this" context?

Can anyone figure out what happened to my code below?

From the documentation, it looks like the method thisin Mongoose .pre('save')should be the model itself, but in my code below the thisempty object ends.

const Mongoose = require('./lib/database').Mongoose;
const Bcrypt = require('bcrypt');

const userSchema = new Mongoose.Schema({
    email: { type: String, required: true, index: { unique: true } },
    password: { type: String, required: true }
});

userSchema.pre('save', (next) => {

    const user = this;

    Bcrypt.genSalt((err, salt) => {

        if (err) {
            return next(err);
        }

        Bcrypt.hash(user.password, salt, (err, encrypted) => {

            if (err) {
                return next(err);
            }

            user.password = encrypted;
            next();
        });
    });
});

const User = Mongoose.model('User', userSchema);

When saving the user, I get the following error [Error: data and salt arguments required].

function createUser(email, password, next) {

    const user = new User({
        email: email,
        password: password
    });

    user.save((err) => {

        if (err) {
            return next(err);
        }

        return next(null, user);
    });
}

createUser('test@email.com', 'testpassword', (err, user) => {

    if (err) {
        console.log(err);
    }
    else {
        console.log(user);
    }

    process.exit();
});

If I delete .pre('save'), then it will save, of course. The version of Mongoose that I am using is 4.2.6.

+4
source share
3 answers

. . , diff

var obj = {};

obj.func1 = function () {
    console.log(this === obj);
};

obj.func2 = () => {
    console.log(this === obj);
};

obj.func1(); // true
obj.func1.bind(obj)(); // true

obj.func2(); // false
obj.func2.bind(obj)(); // false
+6

. , Arrow ES6 , , .

userSchema.pre('save', function (next) {

    Bcrypt.genSalt((err, salt) => {

        if (err) {
            return next(err);
        }

        Bcrypt.hash(this.password, salt, (err, encrypted) => {

            if (err) {
                return next(err);
            }

            this.password = encrypted;
            next();
        });
    });
});

Michelem , , ES6, , .

+5

, :

userSchema.pre('save', (next) => {

    var user = this;

    // Try this
    // console.log(user);

    Bcrypt.genSalt(function (err, salt) {

        if (err) {
            return next(err);
        }

        Bcrypt.hash(user.password, salt, null, function (err, encrypted) {

            if (err) {
                return next(err);
            }

            user.password = encrypted;
            next();
        });
    });
});

, , , .

0

Source: https://habr.com/ru/post/1616323/


All Articles