I'm trying to create a basic register/sign up web app with Express, Vue.js and MongoDB.
I have written some backend validation such as checking the all the fields are filled in and the passwords match etc... and then push a string of the error message into an array if the user fails the validation.
If a user tries to sign up on the front end and fails some part of the validation the user is not inserted into the database but to message is displayed as to why and that what I'm having trouble with.
router.post("/register", (req, res) => {
const name = req.body.name;
const email = req.body.email;
const password = req.body.password;
const password2 = req.body.password2;
let errors = [];
// check required fields
if (!name || !email || !password || !password2) {
errors.push({ msg: "please fill in all fields" });
}
// check for errors
if (password !== password2) {
errors.push({ msg: "Passwords do not match" });
}
// password validation
if (password.length < 6) {
errors.push({ msg: "Password to short" });
}
if (errors.length > 0) {
// if there are errors redirect
res.redirect("/");
console.log(errors);
} else {
// res.send("pass");
// check if the user already exists:
User.findOne({ email: email }).then(user => {
if (user) {
// User exists
// if you have found one user
// then user exists and send to home page
errors.push({ msg: "Email is already registered" });
res.redirect("/");
console.log(errors);
} else {
// create new user by using the keyword 'new'
// name is equal to const name = req.body.name; etc...
const newUser = new User({
name: name,
email: email,
password: password
});
console.log(newUser + " hi new user");
// Hash Password before insert into db
bcrypt.genSalt(10, (err, salt) =>
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
// set PS to hashed PS
newUser.password = hash;
// save user
// insert into db then redirect to login
newUser
.save()
.then(user => {
res.redirect("/login");
})
.catch(err => {
console.log(err);
});
})
);
}
});
}
});
Vue:
name: "RegisterForm",
// data is a function that
// returns an object
data: () => ({
errorMessage: "",
user: {
name: "",
email: "",
password: "",
password2: ""
}
}),
// watch allows you to run a function
// any time data changes
watch: {
user: {
handler() {
this.errorMessage;
},
// deep means anytime data changes this watch will run
deep: true
}
},
methods: {
register() {
// clear error message on register
this.errorMessage = "";
// use keyword 'this' to refer to the current object 'methods'
if (this.validUser()) {
// send data to server
axios({
method: "post",
url: "http://localhost:4000/register",
data: {
name: this.user.name,
email: this.user.email,
password: this.user.password,
password2: this.user.password2
}
})
.then(response => {
console.error(response)
})
.catch(error => {
console.error(error)
});
}
},
validUser() {
// if (this.user.password !== this.user.password2) {
// this.errorMessage = "Passwords must match";
// return false;
// } else {
return true;
// }
// }
}
}
};
There is some frontend validation that works (by doing this.errorMessage = "Passwords must match or some error";) and shows a message but I need to show the errors from "let errors = []"
At the moment I'm currently getting a 'ReferenceError: error is not defined' error in the console when typing in invalid data such as two none matching passwords.