2

I am using express/node to create a back-end api for authentication/authorization and using mongodb to store the data.

I'm using express-validator to validate the input req. I want to validate whether a username already exists or not - the library recommends i should use an async function to do this.

Although it returns the data with the correct error message in postman, my server crashes with the message.

Error: Can't set headers after they are sent.

Server.js

app.use(validator({ customValidators: { isUsernameAvailable: function(username) { return new Promise(function(resolve, reject) { User.findOne({'username': username}, function(err, results) { if(err) { return resolve(err); } reject(results); }); }); } } })); 

auth.route.js

var express = require('express'); var router = express.Router(); var controller = require('../controllers/auth.controller'); var middleware = require('../middleware/auth.middleware'); router.post('/login', controller.login); router.post('/register', middleware.register, controller.register); module.exports = router; 

auth.middleware.js

module.exports.register = function(req, res, next) { req.checkBody({ 'username': { notEmpty: true, errorMessage: 'Username is required' }, 'email': { notEmpty: true, isEmail: { errorMessage: 'Invalid Email Address' }, errorMessage: 'Email is required' }, 'password': { notEmpty: true, errorMessage: 'Password is required' }, 'password_confirmation': { notEmpty: true, errorMessage: 'Password Confirmation is required' } }); req.assert('password_confirmation', 'Passwords do not match').equals(req.body.password); req.check('username', 'This username is already taken').isUsernameAvailable(); var errors = req.validationErrors(true); if(errors) { return res.json({ success: false, errors: errors }); } req.asyncValidationErrors().catch(function(errors) { if(errors) { return res.json({ success:false, errors: errors }); }; }); next(); } 
2

1 Answer 1

1

I think it's because the following blocks are both run:

var errors = req.validationErrors(true); if(errors) { return res.json({ success: false, errors: errors }); } req.asyncValidationErrors().catch(function(errors) { if(errors) { return res.json({ success:false, errors: errors }); }; }); 

The documentation says that you should use one or the other. req.validationErrors(true); is for synchronous, mapped errors whereas req.asyncValidationErrors() is for async un-mapped errors. At the minute, you are using both - both of them are getting run and trying to send a response (which is why you are getting the message: can't set headers after they are sent.

See the validation errors section on their readme for more information.

Sign up to request clarification or add additional context in comments.

Comments