I am trying to validate a sign in form. Right now I am struggling to get the username and email validation parts to work correctly.
Both of these fields are supposed to be unique, as specified in my schema.
var userSchema = new mongoose.Schema({
username: {type:String,required:true,trim:true,unique:true},
password:{type:String,required:true},
email:{type:String,required:true,unique:true},
verified:{type:Boolean,required:true},
dateCreated:{type:Date,default:Date.now}
});
I also have a statics method defined on the schema.
userSchema.statics.validateSignUp = function(username,useremail,password,passwordConfirmation,callback,next){
var isValid = true;
var User = this;
var errorObject = {};
if(username.trim().length >= 5){
//check to see if username already exists
User.findOne({'username': username}).exec(function(err,user){
if(err){
return next(err);
}
if(user){
isValid = false;
errorObject.username = 'Username is already taken.';
}
});
}else{
isValid = false;
errorObject.username = 'Username must be at least 5 chars long.';
}
//check to see if password is greater than 5 characters
//if not add to responseJson errors
if(password.length < 5){
isValid = false;
errorObject.password = 'Password must be at least 5 chars long.';
}
//check password confirmation
if(password !== passwordConfirmation){
isValid = false;
errorObject.passwordConfirm = 'Passwords do not match.';
}
//check email against regex
var emailRe = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if(emailRe.test(useremail)){
User.findOne({'email':useremail}).exec(function(err,user){
if(err){
return next(err);
}
if(user){
isValid = false;
errorObject.email = 'User with this email already exists.';
}
});
}else{
isValid = false;
errorObject.email = 'Email is not valid.';
}
if(!isValid){
console.log('not valid')
return errorObject;
}else{
console.log('valid')
callback()
}
}
The code is supposed to to see if a username and email already exists in the database before attempting to save through a callback function. However, the method continuously returns isValid = true, when I test it. I assume this is due to Node's asynchronous nature. If so what is a good way to handle this sort of thing?
Here is a sample code using Promise
. I have broken up the validation into smaller functions (each returns a promise
) and then chained these promises.
Ideally it would be simpler to return a promise from the main function, but then keeping in mind that your remaining code is already setup with callback
, next
etc, I have kept the callback way. Usage example is at the end of the code.
Also, do you really need next? You have a callback!
See usage example at the end of the code.
userSchema.statics.validateSignUp = function (username, useremail, password, passwordConfirmation, callback, next) {
var isValid = false;
var User = this;
var errorObject;
const checkUsername = function () {
return new Promise(function (resolve, reject) {
errorObject.username = 'Username must be at least 5 chars long.';
if (username.length < 5) return resolve(errorObject);
User.findOne({ username: username }).exec(function (err, user) {
if (err) return reject(err);
if (user) errorObject.username = 'Username is already taken.';
return resolve();
});
});
};
const checkPassword = function () {
return new Promise(function (resolve, reject) {
if (password.length < 5) {
errorObject.password = 'Password must be at least 5 chars long.';
return resolve();
}
if (password === passwordConfirmation) return resolve();
errorObject.password = 'Passwords do not match.';
resolve();
});
};
const checkEmail = function () {
return new Promise(function (resolve, reject) {
var emailRe = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (!emailRe.test(useremail)) {
errorObject.email = 'Email is not valid.';
resolve();
}
User.findOne({ 'email': useremail }).exec(function (err, user) {
if (err) return reject(err);
if (user) {
errorObject.email = 'User with this email already exists.';
resolve();
}
isValid = true;
resolve();
});
});
};
checkUsername()
.then(checkPassword)
.then(checkEmail)
.then(function () {
// if (isValid) console.log('valid');
// else console.log('not valid');
callback(errorObject, isValid);
})
.catch(function (err) {
next(err);
});
};
//USAGE EXAMPLE:
// userModel.validateSignUp('foo', 'foo@bar.com', 'bar', 'bar', function (err, valid) {
// if (err) return console.log(err);
// if (valid) console.log('valid');
// else console.log('not valid');
// }, next);
Hope this helps you.
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.