user3242861
user3242861

Reputation: 1929

How to use a custom express-validator?

I'm developing a register form and I'm using express-validator to validate fields but I'm having troubles in validate if email already exists.

I did a select to check if the inserted email already exists but it returns me always that email exists.

I tried other ways but didn't work.

This is my post request:

routes.post('/register', function(req,res)
{
    var email = req.body.email;
    var username = req.body.username;
    var password = req.body.password;
    var password2 = req.body.password2;

    // Validation
    req.checkBody('email', 'Email is required').notEmpty();
    req.checkBody('email', 'Email is not valid').isEmail();
  req.checkBody('email', 'Email already exists').custom(value => {
    return User.findUserByEmail(value).then(function(user) {
      throw new Error('this email is already in use');
    })
  });

    req.checkBody('username', 'Username is required').notEmpty();
    req.checkBody('password', 'Password is required').notEmpty();
    req.checkBody('password2', 'Passwords do not match').equals(req.body.password);

    var errors = req.validationErrors();

    if(errors){
    console.log(errors);
        res.render('register',{
            errors:errors
        });
    } else {
    console.log("passed");

        var newUser = {
            email:email,
            username: username,
            password: password
        };


        User.createUser(newUser, function(err, User){
            if(err) throw err;
            console.log(User);
        });

        req.flash('success_msg', 'You are registered and can now login');

        res.redirect('/login');
    }
});

And my function findUserByEmail:

module.exports.findUserByEmail = function(email, callback){
  var connection = db.setDB('DB1');
  connection.then(result => {
    var request = new mssql.Request(conn);
    console.log("SELECT * FROM u_users WHERE email = '"+email+"'");
    var exists = request.query("SELECT * FROM u_users WHERE email = '"+email+"'");

    Promise.all([exists]).then(function(results)
    {

      console.log(results);
      if(results[0].length == 0)
      {
        console.log("1");
        return false;
      }
      console.log("2");
      return true;
    }).catch(function(err)
    {
      console.log("Error verifying email...");
      console.log(err);
    });
  });
}

If I do this way it returns me an error Cannot read property 'then' of undefined.

What am I doing wrong?

Upvotes: 1

Views: 16579

Answers (1)

gustavohenke
gustavohenke

Reputation: 41440

Regarding the error Cannot read property 'then' of undefined., this happens because you're not returning the promise from your findUserByEmail function.

In addition to this, your custom validator will always fail if you keep it as is.

Your findUserByEmail is only returning true/false, what means "resolve this promise with this value".
You might want to change it to return the found user (and also make its name suggest what it really does!):

module.exports.findUserByEmail = function(email, callback){

    var request = new mssql.Request(conn);
    console.log("SELECT * FROM u_users WHERE email = '"+email+"'");
    var query = request.query("SELECT * FROM u_users WHERE email = '"+email+"'");

    return query.then(function(results) {
      return results[0];
    }).catch(function(err) {
      console.log("Error verifying email...");
      console.log(err);
      throw err;
    });
}

Now you need to make your custom validator check if any user was returned from that function:

req.checkBody('email', 'Email already exists').custom(value => {
    return User.findUserByEmail(value).then(function(user) {
        if (user) {
            throw new Error('this email is already in use');
        }
    })
});

And you're done!

Upvotes: 0

Related Questions