【问题标题】:Type Error: Cannot set property '$op' of undefined类型错误:无法设置未定义的属性“$ op”
【发布时间】:2020-10-16 15:36:41
【问题描述】:

我试图按照视频教程使用 Node.js、Express.js 和 MongoDB 制作应用程序,但遇到了这个问题:

我在猫鼬模型中创建了一个 UserSchema 和函数:

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

var UserSchema = mongoose.Schema({
    username: {
        type: String
    },
    email: {
        type: String
    },
    password: {
        type: String,
        bcrypt: true
    },
    type: {
        type: String
    }
});

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

//single user by id

module.exports.getUserById = (id, callback)=>{
    User.findById(id, callback);
}

//single user by name

module.exports.getUserByUsername = (username, callback)=>{
    var query = {username: username};
    User.findOne(query, callback);
}

//compare password
module.exports.comparePassword = (candidatePassword, hash, callback)=>{
    bcrypt.compare(candidatePassword, hash, (err, isMatch)=>{
        if(err) throw err;
        callback(null, isMatch);
    });
}

//create student user
module.exports.saveStudent = (newUser, newStudent, callback)=>{
    bcrypt.hash(newUser.password, 10, (err,hash)=>{
        if(err) throw err;
        newUser.password = hash;
        console.log("student saved");
        async.parallel([newUser.save, newStudent.save], callback);
    });
}

//create instructor user
module.exports.saveInstructor = (newUser, newInstructor, callback)=>{
    bcrypt.hash(newUser.password, 10, (err,hash)=>{
        if(err) throw err;
        newUser.password = hash;
        console.log("instructor saved");
        async.parallel([newUser.save, newInstructor.save], callback);
    });
}

创建用户的表单是:

<%- include ('../partials/header') %>

<% if(locals.errors){ %>
    <% for(var i=0; i < errors.length; i++){ %>
        <div class="aler alert-danger m-2"> <%= errors[i].msg %></div>
    <%} %>
<% } %>
<form id="regForm" method="post" action="/users/register">
    <div>
        <label>Account Type</label>
        <select name="type">
            <option value="student">Student</option>
            <option value="instructor">Instructor</option>
        </select>
    </div>
    <br />
    <div>
        <label>First Name: </label>
        <input type="text" name="first_name" >
    </div><br />
    <div>
        <label>Last Name: </label>
        <input type="text" name="last_name" >
    </div><br />
    <div>
        <label>Street Address: </label>
        <input type="text" name="street_address" >
    </div><br />
    <div>
        <label>City: </label>
        <input type="text" name="city" >
    </div><br />
    <div>
        <label>State: </label>
        <input type="text" name="state" >
    </div><br />
    <div>
        <label>Zip: </label>
        <input type="text" name="zip" >
    </div><br />
    <div>
        <label>Email Address: </label>
        <input type="text" name="email" >
    </div><br />
    <div>
        <label>Username: </label>
        <input type="text" name="username" >
    </div><br />
    <div>
        <label>Password: </label>
        <input type="password" name="password" >
    </div><br />
    <div>
        <label>Password Confirm: </label>
        <input type="password" name="password2" >
    </div><br />
    <div>
        <input type="submit" value="Register">
    </div>
</form>

<%- include ('../partials/footer') %>

表格的发布路线是:

router.post('/register', function(req, res, next) {
    // Get Form Values
    var first_name      = req.body.first_name;
    var last_name       = req.body.last_name;
    var street_address  = req.body.street_address;
    var city            = req.body.city;
    var state           = req.body.state;
    var zip             = req.body.zip;
    var email           = req.body.email;
    var username        = req.body.username;
    var password        = req.body.password;
    var password2       = req.body.password2;
    var type            = req.body.type;

    // Form Validation
    req.checkBody('first_name', 'First name field is required').notEmpty();
    req.checkBody('last_name', 'Last name field is required').notEmpty();
    req.checkBody('email', 'Email field is required').notEmpty();
    req.checkBody('email', 'Email must be a valid email address').isEmail();
    req.checkBody('username', 'Username field is required').notEmpty();
    req.checkBody('password', 'Password field is required').notEmpty();
    req.checkBody('password2', 'Passwords do not match').equals(req.body.password);

    errors = req.validationErrors();

    if(errors){
        res.render('users/register', {
            errors: errors
        });
    } else {
        var newUser = new User({
            email: email,
            username:username,
            password: password,
            type: type
        });

        if(type == 'student'){
            console.log('Registering Student...');

            var newStudent = new Student({
                first_name: first_name,
                last_name: last_name,
                address: [{
                    street_address: street_address,
                    city: city,
                    state: state,
                    zip: zip
                }],
                email: email,
                username:username
            });

            User.saveStudent(newUser, newStudent, function(err, user){
                console.log('Student created');
            });
        } else {
            console.log('Registering Instructor...');
            var newInstructor = new Instructor({
                first_name: first_name,
                last_name: last_name,
                address: [{
                    street_address: street_address,
                    city: city,
                    state: state,
                    zip: zip
                }],
                email: email,
                username:username
            });

            User.saveInstructor(newUser, newInstructor, function(err, user){
                console.log('Instructor created');
            });
        }

        req.flash('success_msg', 'User Added');
        res.redirect('/');
    }
});

我在尝试提交表单时收到以下错误:

D:\webpages\elearn\node_modules\mongoose\lib\model.js:460
  this.$op = 'save';
           ^

TypeError: Cannot set property '$op' of undefined
    at Model.save (D:\webpages\elearn\node_modules\mongoose\lib\model.js:460:12)
    at D:\webpages\elearn\node_modules\async\lib\async.js:567:21
    at D:\webpages\elearn\node_modules\async\lib\async.js:246:17
    at D:\webpages\elearn\node_modules\async\lib\async.js:122:13
    at _each (D:\webpages\elearn\node_modules\async\lib\async.js:46:13)
    at async.each (D:\webpages\elearn\node_modules\async\lib\async.js:121:9)
    at _asyncMap (D:\webpages\elearn\node_modules\async\lib\async.js:245:13)
    at Object.map (D:\webpages\elearn\node_modules\async\lib\async.js:216:23)
    at _parallel (D:\webpages\elearn\node_modules\async\lib\async.js:565:20)
    at Object.async.parallel (D:\webpages\elearn\node_modules\async\lib\async.js:595:9)
    at D:\webpages\elearn\models\user.js:59:15
    at D:\webpages\elearn\node_modules\bcryptjs\dist\bcrypt.js:1353:21
    at Immediate.next (D:\webpages\elearn\node_modules\bcryptjs\dist\bcrypt.js:1233:21)
    at processImmediate (internal/timers.js:456:21)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! elearn-new@0.0.0 start: `node ./bin/www`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the elearn-new@0.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Vidhi\AppData\Roaming\npm-cache\_logs\2020-10-16T15_25_02_171Z-debug.log

很久以来我一直坚持这一点。请帮忙!

【问题讨论】:

    标签: node.js mongodb express mongoose


    【解决方案1】:

    您应该使用模型的静态方法async/await函数,而不是使用独立的函数。这样就可以调用所有schema的方法了。

    var UserSchema = mongoose.Schema({
        username: {
            type: String
        },
        email: {
            type: String
        },
        password: {
            type: String,
            bcrypt: true
        },
        type: {
            type: String
        }
    });
    
    UserSchema.static({
     async getUserById(id) {
       const user = await this.findById(id);
       return user;
     }
     async getUserByUsername(username) {
       const user = await this.findOne({username: username});
       return user;
     }
     async saveInstructorUser(newUser, newInstructor) { // these parameters are plain object
       const hash = bcrypt.hashSync(newUser.password, 10);
       const [,student] = await Promise.all([ 
                           this.create({...newUser, password: hash}), 
                           this.model('Instructor').create(newInstructor) //Need replace with correct schema name
                          ]);
       return student;
     }
    });
    
    module.exports = mongoose.model('User', UserSchema);
    
    

    【讨论】:

      【解决方案2】:

      这样做对我有帮助:

      async.parallel([newUser.save.bind(newUser), newStudent.save.bind(newStudent)], callback);
      

      async.parallel([newUser.save.bind(newUser), newInstructor.save.bind(newInstructor)], callback);
      

      【讨论】:

        【解决方案3】:

        使用它会 100% 工作

        enter code hereasync.parallel([newUser.save.bind(newUser), newStudent.save.bind(newStudent)], callback);
        async.parallel([newUser.save.bind(newUser), newInstructor.save.bind(newInstructor)], callback);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-10-14
          • 1970-01-01
          • 2022-01-01
          • 1970-01-01
          • 2019-01-02
          • 1970-01-01
          相关资源
          最近更新 更多