Search code examples
javascriptnode.jsexpress-validator

Unable to pass custom express-validator check


The purpose of the following code is to check whether an email already exists in MongoDB, using express-validator:

    app.post('/registerPage',[check('email').custom((email) => {
    // connect to database
    let MongoClient = require('mongodb').MongoClient;
    let url = 'mongodb://localhost';
    MongoClient.connect(url, function(err, client) {
        if (err) throw err;
        let db = client.db('Mydatabase');
        // search database
        return db.collection('users').findOne({
            email: email
        }).then(user => {
                if (user) {
                   console.log(user); // here console shows correct record in database
                   return Promise.reject('E-mail already in use');
                }
                // otherwise, it returns null
        });
    })
}).withMessage('Error Message Example')], (req, res) => {
    // Handle the request
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
       return res.status(422).json({ errors: errors.array() })
    }
  });

When email already exists, console shows Promise.reject('E-mail already in use');.

The problem is when email does not exist, although it doesn't show Promise.reject, the code cannot process any further, validationResult(req) is not empty, so it still prints out the error message 'Error Message Example'. But there isn't any problem with non-custom validators which can successfully pass the checks.

I tried to add an else statement where !user, it doesn't work.

The question is how to pass the custom validation check, or why the array validationResult(req) is not empty even it should be? How do I make sure validationResult is empty after all checks were passed.


Solution

  • The issue is you are returning the promise in the callback of MongoClient.connect and not the validator function. Try using Promise wrapper like:

    app.post('/registerPage',[check('email').custom((email) => {
        return new Promise((resolve, reject) => {
            // connect to database
            let MongoClient = require('mongodb').MongoClient;
            let url = 'mongodb://localhost';
            MongoClient.connect(url, function(err, client) {
                if (err) throw err;
                let db = client.db('Mydatabase');
                // search database
                return db.collection('users').findOne({
                    email: email
                }).then(user => {
                    if (user) {
                    console.log(user); // here console shows correct record in database
                    return reject('E-mail already in use');
                    }
                    return resolve();
                });
            })
    
        });
    }).withMessage('Error Message Example')], (req, res) => {
        // Handle the request
        const errors = validationResult(req);
        if (!errors.isEmpty()) {
        return res.status(422).json({ errors: errors.array() })
        }
    });
    

    Hope this helps!