I am working on a blogging application (click the link to see the GitHub repo) with Express, EJS and MongoDB.
Before submitting a
try change your if statement from this:
if (!errors.isEmpty()) {
console.log('there are no validation errors');
} else {
console.log(errors);
}
}
to this:
exports.addPost = (req, res, next) => {
// Form validation rules
check('title', '<your error message>')
.not()
.isEmpty();
check('excerpt', '<your error message>')
.not()
.isEmpty();
check('body', '<your error message>')
.not()
.isEmpty();
const errors = validationResult(req);
const errors = validationResult(req);
if (!errors.isEmpty()) {
console.log(errors.array());
}
}
Edit
If you would like to send an response to your front-end replace the console.log()
command into res.send()
then parse the answer in your front-end
like so:
if (!errors.isEmpty()) {
return res.send(errors.array());
// can also send an status and catch it
// by sending res.status(400).send(errors.array());
}
Hopefully this makes sense
from what i see in the documentation of express-validator you need to provide an array of validation rules(those checks
at the top of your controller) when you define the route.
It doesn't make much sense for them to be at the top of the request handler since the express-validator won't be able to access the context that provides the request to be validated.
So in the router you need something like this:
router/front-end/posts.js
const validationRules = [// Form validation rules
check('title', 'The title field id required')
.not()
.isEmpty(),
check('excerpt', 'The excerpt field id required')
.not()
.isEmpty(),
check('body', 'The full text field id required')
.not()
.isEmpty()];
// create new post
router.post('/', validationRules, postsController.addPost);
controllers/front-end/posts.js
exports.addPost = (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
console.log(errors.array());
}
if (!errors.isEmpty()) {
res.render('admin/addpost', {
layout: 'admin/layout',
website_name: 'MEAN Blog',
page_heading: 'Dashboard',
page_subheading: 'Add New Post',
errors: errors
});
req.flash('danger', errors);
req.session.save(() => res.redirect('/dashboard'));
} else {
const post = new Post();
post.title = req.body.title;
post.short_description = req.body.excerpt
post.full_text = req.body.body;
post.save(function(err){
if(err){
console.log(err);
return;
} else {
req.flash('success', "The post was successfully added");
req.session.save(() => res.redirect('/dashboard'));
}
});
}
}
Everything else seem ok, at least from the code you posted.
You are rendering a template then trying to show flash and then redirect again. Change it to this
req.flash('danger', errors);
req.session.save(() => res.redirect('/dashboard'));
Forget the render... It makes no sense for you to have it there. What render does, it renders and returns a template. Therefore your req.flash and redirect never happens or it happens after the header have already been sent.
res.render() definition:
Renders a view and sends the rendered HTML string to the client. Optional parameters:
locals, an object whose properties define local variables for the view. callback, a callback function. If provided, the method returns both the possible error and rendered string, but does not perform an automated response. When an error occurs, the method invokes next(err) internally.
AND
exports.addPost = (req, res, next) => {
// Form validation rules
req.check('title').not().isEmpty().withMessage("The title field is mandatory");
req.check('body').not().isEmpty().withMessage("The full text field is mandatory");
const errors = req.validationErrors();
use this code in index.js to get flash error messages locally in EJS ,
app.use(function (req, res, next) {
res.locals.messages = req.flash();
next();
});
Maybe you should start with this https://express-validator.github.io/docs/ then gradually customise it to fit your need so that you can catch any error along the way.
exports.addPost = (req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
req.flash('errors', errors.array())
req.session.save(() => res.redirect('../addpost'));
//return res.status(400).send(errors.array());
} else {
const post = new Post();
post.title = req.body.title;
post.short_description = req.body.excerpt
post.full_text = req.body.body;
post.save(function(err){
if(err){
console.log(err);
return;
} else {
req.flash('success', "The post was successfully added");
req.session.save(() => res.redirect('/dashboard'));
}
});
}
}
messages.ejs
<div id="messages" class="text-center">
<% Object.keys(messages).forEach(function (type) { %>
<% messages[type].forEach(function (message) { %>
<% if (type === 'errors') {%>
<div class="alert alert-<%= type %>"><%= message.msg %></div>
<%} else { %>
<div class="alert alert-<%= type %>"><%= message %></div>
<% } %>
<% }) %>
<% }) %>
I guess this is what you intended to do