Julian Veling
Julian Veling

Reputation: 357

Form validation and Node JS - avoiding pyramid of doom

I am new to Node and am trying to do some user registration form validation. I would like to refactor the following code to get rid of the pyramid if possible. Im using Express Validator within the userService module to check against empty fields and for email validation, but the isValueUnique function is just a Mongoose findOne query. Im using Graphics Magick to resize the image. Any suggestions most welcome:

router.post('/register', function(req, res, next){
  userCheck = userService.checkRegistration(req)
  if(userCheck.errors){
    return res.render('user/register', { 
      errors: userCheck.errors,
      message: req.flash('error'),
      title: 'People Power | Register'
    })
  }
  User.isValueUnique({username: req.body.username}, function(err, user){
    if(user){
      return res.render('user/register', { message: 'Username already taken. Please choose another.', title: 'People Power | Register' });  
    }else{
      User.isValueUnique({ email: req.body.email }, function(err, user){
        if(user){
          return res.render('user/register', { message: 'Email already registered. Please try again.', title: 'People Power | Register' }); 
        } else{
          User.createUser(userCheck, function(err, user){
            if(err) throw err;
            userService.resizeImage(userCheck, function(){
              req.login(user, function(err){
                req.flash('success', 'You have registered successfully, and are now logged in!')
                res.redirect('/')
              })
            });
          });
        }             
      })
    }   
  })             
});

Upvotes: 0

Views: 139

Answers (1)

Artem Baranovskii
Artem Baranovskii

Reputation: 1003

You could use async#waterfall to improve "callback hell", so your code might looks like the following:

async.waterfall([

    function (callback) {
        User.isValueUnique({username: req.body.username}, callback);
    },

    function (user, callback) {
        if (user) {
            return res.render('user/register', { message: 'Username already taken. Please choose another.', title: 'People Power | Register' });  
        }  
        User.isValueUnique({ email: req.body.email}, callback); 
    }

    function (user, callback) {
        if (user) {
            return res.render('user/register', { message: 'Email already registered. Please try again.', title: 'People Power | Register'};   
        }
        User.createUser(userCheck, callback);
    },

    function (user, callback) {            
        userService.resizeImage(userCheck, callback);            
    },

    function (callback) {
        req.login(user, function(err) {
            req.flash('success', 'You have registered successfully, and are now logged in!')
                res.redirect('/')
            });   
        } 
], function (err) {
    if (err) throw err;
});

Also I suggest to look at PassportJS module that already has suite of patterns for implementation of users registration feature.

Upvotes: 1

Related Questions