Express.js application bug: req.validationErrors() method does not work

≡放荡痞女 提交于 2020-03-12 06:20:12

问题


I am working on a blogging application (click the link to see the GitHub repo) with Express, EJS and MongoDB.

Before submitting a new post, of course, I have to validate the form entries. I use express-validator version 6.3.0.

My addPost controller:

exports.addPost = (req, res, next) => {
    // 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();

    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'));
            }
        });
    }
}

The Post model:

const postSchema = new mongoose.Schema({
    title: {
        type: String,
        required: true
    },
    short_description: {
        type: String,
        required: true
    },
    full_text: {
        type: String,
        required: true
    },
    post_image: {
        type: String,
        required: false
    },
    updated_at: {
        type: Date,
        default: Date.now()
    },
    created_at: {
        type: Date,
        default: Date.now()
    }
});

The error messages are nor rendered in the view, which looks like this:

<div id="messages" class="text-center">
    <% Object.keys(messages).forEach(function (type) { %>
        <% messages[type].forEach(function (message) { %>
            <div class="alert alert-<%= type %>"><%= message %></div>
        <% }) %>
    <% }) %>
</div>

What am I doing wrong?


回答1:


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.




回答2:


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();



回答3:


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




回答4:


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.



来源:https://stackoverflow.com/questions/60548245/express-js-application-bug-req-validationerrors-method-does-not-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!