#node.js #mongodb #express #mongoose
#node.js #mongodb #выразить #мангуст
Вопрос:
Я пытался следовать видеоуроку, чтобы создать приложение с помощью Node.js , Express.js и мы с MongoDB столкнулись с этой проблемой:
Я создавал пользовательскую схему и функции в модели mongoose:
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:webpageselearnnode_modulesmongooselibmodel.js:460
this.$op = 'save';
^
TypeError: Cannot set property '$op' of undefined
at Model.save (D:webpageselearnnode_modulesmongooselibmodel.js:460:12)
at D:webpageselearnnode_modulesasynclibasync.js:567:21
at D:webpageselearnnode_modulesasynclibasync.js:246:17
at D:webpageselearnnode_modulesasynclibasync.js:122:13
at _each (D:webpageselearnnode_modulesasynclibasync.js:46:13)
at async.each (D:webpageselearnnode_modulesasynclibasync.js:121:9)
at _asyncMap (D:webpageselearnnode_modulesasynclibasync.js:245:13)
at Object.map (D:webpageselearnnode_modulesasynclibasync.js:216:23)
at _parallel (D:webpageselearnnode_modulesasynclibasync.js:565:20)
at Object.async.parallel (D:webpageselearnnode_modulesasynclibasync.js:595:9)
at D:webpageselearnmodelsuser.js:59:15
at D:webpageselearnnode_modulesbcryptjsdistbcrypt.js:1353:21
at Immediate.next (D:webpageselearnnode_modulesbcryptjsdistbcrypt.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:UsersVidhiAppDataRoamingnpm-cache_logs2020-10-16T15_25_02_171Z-debug.log
Я застрял с этим уже давно. Пожалуйста, помогите!
Ответ №1:
Вы должны использовать статические методы model и функции async / await вместо независимых функций. Таким образом, вы можете вызвать все методы схемы.
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);