Access request body in check function of express-validator v4

13,126

After fiddling around for a while, I found a way to achieve this by using custom validators. The validator function passed to the custom method accepts an object containing the request body:

router.post(
    "/submit",
    [
    // Check validity
    check("email", "Invalid email").isEmail(),
    check("password", "invalid password")
        .isLength({ min: 4 })
        .custom((value,{req, loc, path}) => {
            if (value !== req.body.confirmPassword) {
                // trow error if passwords do not match
                throw new Error("Passwords don't match");
            } else {
                return value;
            }
        })
    ],
    (req, res, next) => {
        // return validation results
        const errors = validationResult(req);

        // do stuff
    });
Share:
13,126
Martin Reiche
Author by

Martin Reiche

I am a freelance full-stack javascript web developer. I love coding, both for my personal hobby projects as well as for my customers. I like building highly customized web applications using modern web technologies like React.js or Next.js for the front-end and serverless architectures like AWS Lambda or Google firebase for back-end logic. I am always looking for new challenges and I love to solve problems. I have a PhD in Neuroscience and like to tackle complex data related problems. Yet I am still looking for ways to integrate my scientific passion in my freelance coding career. If you have an interesting project and need help, please do not hesitate to contact me.

Updated on July 26, 2022

Comments

  • Martin Reiche
    Martin Reiche almost 2 years

    I just started using express.js with express-validator to validate some input data and I have problems accessing the request body in the new check API that was introduced in version 4.0.0.

    In older versions, you simply added express-validator as middleware in your app.js somewhere after body-parser:

    // ./app.js
    const bodyParser = require("body-parser");
    const expressValidator = require("express-validator");
    
    const index = require("./routes/index");
    
    const app = express();
    
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(expressValidator());
    

    Then in my index route, I could check the fields in the final callback function of the post method.

    // ./routes/index.js
    const express = require("express");
    const router = express.Router();
    
    router.post("/submit", (req, res, next) => {
        // check email
        req.check('email','Invalid email address').isEmail()
        // check if password is equal to password confirmation
        req.check('password', 'Invalid password')
        /* Access request body to compare password 
        field with password confirmation field */
        .equals(req.body.confirmPassword)
    
        // get errors
        const errors = req.validationErrors();
    
        // do stuff
    });
    

    Like in this example, I could easily check whether the values of my password field and the password confirmation field of my form are equal. However, since version 4, they have a new API which requires you to load the express-validator directly in your router file and pass the check functions as array of functions before the final callback in the post method, like this:

    // ./routes/index.js
    const express = require("express");
    const router = express.Router();
    const { check, validationResult } = require("express-validator/check");
    
    router.post(
        "/submit",
        [
            // Check validity
            check("email", "Invalid email").isEmail(),
            // Does not work since req is not defined
            check("password", "invalid password").isLength({ min: 4 })
            .equals(req.body.confirmPassword) // throws an error
        ],
        (req, res, next) => {
        // return validation results
        const errors = validationResult(req);
    
        // do stuff
    });
    

    This doesn't work since req is not defined. So my quetsion is: how can I access the request object in a check() chain to compare two different fields with the new express-validator API? Thanks very much in advance!