简体   繁体   中英

Inside Schema method scopes “this” is empty {} in Mongoose 4.4.12

The object "this" is "{}" when logged to the console inside a Schema method. This occurred one day ago and I've been reading up tutorials and other stack overflow questions, but to no luck have I found a solution as to why.

Here is my model:

var mongoose    = require("mongoose");
var Schema      = mongoose.Schema;
var constants   = require("../config/constants");
var bcrypt      = require("bcrypt-nodejs");


var UserSchema = new Schema({
    name: String,
    email: String,
    password: String,
    authorization:
    {
        type: Number,
        default: constants.authorization.default
    }
});

UserSchema.pre("save", (next) => {
    var user = this;

    /**
     * Only hash the password when it's been modified or if new.
     */

    // #####################################################
    // ERROR
    // if (!query.isModified("password"))
    //            ^
    // TypeError: query.isModified is not a function
    //
    // user and this == {}
    // ####################################################
    if (!user.isModified("password"))
    {
        return next();
    }

    /**
     * hash password
     */
    bcrypt.hash(user.password, null, null, (err, hash) => {
        if (err)
        {
            return next(err);
        }

        user.password = hash;
        return next();
    });
});

// #####################################################
// ERROR
// user.verifyPassword(req.body.password, match => {
//     ^
// TypeError: user.verifyPassword is not a function
//
// this == {}
// ####################################################
UserSchema.methods.verifyPassword = (reqPassword, callback) => {
    bcrypt.compare(reqPassword, this.password, (err, match) => {
        var e = null;
        var m = match;

        if (err)
        {
            e = err;
            m = false;
        }

        return callback(e, m);
    });
};



module.exports = mongoose.model("User", UserSchema);

And this is how I use it (I've marked where the break happens) :

//includes express, mongoose, User, constants. this part is ok.

/**
 * Authenticates a user post request
 *
 * @request email string
 * @request password string
 *
 */
router.post("/", (req, res) => {
    /**
     * Retrieve the user
     */
    User.find(
    {
        email: req.body.email
    },
    (err, user) =>
    {
        /**
         * An error occurred
         */
        if (err)
        {
            return res.json({
                success:    false,
                message:    "An mongodb error occurred.",
                error:      err
            });
        }

        /**
         * Check for problems with the email or password.
         */
        if (!user)
        {
            return res.json({
                success:    false,
                message:    "Email or password was incorrect."
            });
        }

        // ##########################################################
        // ERROR
        // user.verifyPassword(req.body.password, match => {
        //     ^
        // TypeError: user.verifyPassword is not a function
        // ##########################################################
        user.verifyPassword(req.body.password, match => {
            if (!match)
            {
                return res.json({
                    success:    false,
                    message:    "Email or password was incorrect."
                });
            }

            /**
             * User authenticated!
             */
            req.session.user = user;
            res.json({
                success: true,
                message: "Successfully authenticated."
            });
        });

    });
});

router.get("/", (req, res, next) => {
    var admin = new User({
        name: "admin",
        email: "admin@admin.net",
        password: "admin",
        authorization: constants.authorization.admin
    });

    // ########################################################
    // ERROR
    // if (!user.isModified("password"))
    //            ^
    // TypeError: user.isModified is not a function
    // #######################################################
    admin.save(function(err) {
        if (err)
        {
            console.log(err);
        }

        console.log('User saved successfully');
        res.json({ success: true });
    });
});

Does anyone know the problem of this?

The problem might be related to the fact that you're using ES6 arrow syntax instead of a plain function as the callback. ES6 arrow functions change the semantics of the this keyword, which might affect how mongoose handles the callback internally.

Try

UserSchema.pre("save", function(next) {
    // ...
});

instead of

UserSchema.pre("save", (next) => {
    // ...
});

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