简单节点路由器

时间:2018-01-26 02:08:36

标签: node.js express bcrypt

我有一条在Node / Express中创建用户的路由。关于模型中存在的方法,我遇到了一个奇怪的错误。

以下是用户的模型:

'use strict'; 

const mongoose = require('mongoose'); 
const bcrypt = require('bcryptjs'); 

mongoose.Promsie = global.Promise; 

const UserSchema = mongoose.Schema({
    username: { type: String, required: true, unique: true }, 
    password: { type: String, required: true }, 
    email: { type: String, required: true }, 
    firstName: { type: String },
    lastName: { type: String },
    families: [
        {
            family_key: { type: String, required: true }, 
            family_name: { type: String }
        }
    ]
}); 

UserSchema.methods.apiRepr = function() {
    return {
        id: this._id,
        firstName: this.firstName,
        lastName: this.lastName,
        username: this.username,
        email: this.email, 
        families: this.families 
    }; 
}; 

UserSchema.methods.hashPassword = function(password) {
    return bcrypt.hash(password, 10); 
}

UserSchema.methods.validatePassword = function(password) {
    return bcrypt.compare(password, this.password); 
}

const User = mongoose.models.User || mongoose.model('User', UserSchema); 

module.exports = { User }; 

不是特别复杂。但是,我的路线遇到了“hashPassword”方法的问题。当我尝试使用这条路线时,我收到一条错误,上面写着“TypeError:User.hashPassword不是函数”

这是路线(问题接近底部):

router.post('/', jsonParser, (req, res) => {

    // checking that required fields are present

    const requiredFields = ['username', 'password', 'email']; 
    const missingField = requiredFields.find(field => !(field in req.body));

    if(missingField) {
        return res.status(422).json({
            code: 422, 
            reason: 'Validation Error', 
            message: 'Missing field', 
            location: missingField
        });
    }

    // checking the format of string fields

    const stringFields = ['username', 'password', 'email', 'lastname', 'firstname']; 
    const nonStringField = stringFields.find(
        field => field in req.body && typeof req.body[field] !== 'string'
    ); 

    if (nonStringField) {
        return res.status(422).json({
            code: 422, 
            reason: 'Validation Error', 
            message: 'Incorrect field type: expected string', 
            location: nonStringField
        }); 
    }

    // checking the trimming on fields

    const trimmedFields = ['username', 'password', 'email']; 
    const nonTrimmedField = trimmedFields.find(
        field => req.body[field].trim() !== req.body[field]
    ); 

    if (nonTrimmedField) {
        return res.status(422).json({
            code: 422, 
            reason: 'Validation Error', 
            message: 'Cannot start or end with whitespace', 
            location: nonTrimmedField
        }); 
    }

    // checking length of fields with required length

    const sizedFields = {
        username: { min: 1 }, 
        password: { min: 10, max: 72 }
    };
    const tooSmallField = Object.keys(sizedFields).find(field => 
        'min' in sizedFields[field] &&
        req.body[field].trim().length < sizedFields[field].min
    );
    const tooLargeField = Object.keys(sizedFields).find(field => 
        'max' in sizedFields[field] &&
        req.body[field].trim().length > sizedFields[field].max
    ); 

    if (tooSmallField || tooLargeField) {
        return res.status(422).json({
            code: 422, 
            reason: 'Validation Error', 
            message: tooSmallField
            ? `Must be at least ${sizedFields[tooSmallField].min} characters long`
            : `Must be at most ${sizedFields[tooLargeField].max} characters long`,
            location: tooSmallField || tooLargeField
        }); 
    }

    // creating the user

    let { username, firstname, lastname, families, email, password } = req.body; 
    return User.find({ username })
        .count()
        .then(count => {
            if(count > 0) {
                return Promise.reject({
                    code: 422, 
                    reason: 'Validation Error', 
                    message: 'Username already taken', 
                    location: 'username'
                }); 
            }
            return User.hashPassword(password); 
        })
        .then(hash => {
            return User.create({ username, firstname, lastname, families, email, password: hash })
        })
        .then(user => {
            return res.status(201).json(user.apiRepr()); 
        })
        .catch(err => {
            console.error(err)
            res.status(500).json({ code: 500, message: 'Internal server error'})
        })
})

它不喜欢返回User.hashPassword(密码)部分。有关这是什么原因的任何想法?我正在从一个有效的应用程序复制。不知道我在这里做错了什么。

1 个答案:

答案 0 :(得分:0)

node.js中的方法不能直接使用您需要创建模式名称对象的SchemaName,然后使用模式的方法。

例如:

var AnimalSchema = new Schema({
    name: String
  , type: String
});

AnimalSchema.methods.findSimilarType = function findSimilarType (cb) {
  return this.model('Animal').find({ type: this.type }, cb);
};

var Animal = mongoose.model('Animal', AnimalSchema);
var dog = new Animal({ name: 'Rover', type: 'dog' });

dog.findSimilarType(function (err, dogs) {
  if (err) return ...
  dogs.forEach(..);
})

来源:http://mongoosejs.com/docs/2.7.x/docs/methods-statics.html

在您的代码中,您尝试从模型中访问方法。 实例化模型然后使用方法。

如果需要像在代码中使用的那样使用,请尝试使用函数而不是方法。

module.exports.funtionName = function(/*function params*/){
//function body here 

};