javascript - How can I pass parameters to a generic Express middleware function on a per-route basis? -


i've written generic validation function takes object first parameter property required (amongst others) array of strings. used test incoming front end data against keys found in required. here's mockup of how looks - using underscore check isempty:

validator.js

function validaterequest(options, req, done) {   const { body } = req;   const { required } = options;   const errors = {};    if (required && required.length) {     required.foreach(key => {       const value = `${body[key]}`;        if (_.isempty(value)) {         errors[key] = 'this field required';       }     });   }    if (_.isempty(errors)) done({ success: true });   else done({ success: false, errors }); } 

and use such:

routes/auth.js

router.post('/login', (req, res, next) => {   validator.validaterequest({     required: ['identifier', 'password']   }, req, result => {     if (!result.success) return res.status(400).send(result);     next();   }); }, auth.login); 

i'd able use in cleaner fashion, more like:

router.post('/login', validator.validaterequest({   required: ['identifier', 'password'] }), auth.login); 

i'd rather not use app.use because involves me having worry positioning in proper hierarchy of route files , not scalable in sense need be. have other parameters being passed options, validating input numeric, correct zip codes, etc. function above more in-depth example. there way me use on route-by-route basis? there's gotta way middleware functions intercept (req, res, next) without having write out each time.. right?

the answer use higher order function returning function takes (req, res, next) parameters this:

validator.js

function validaterequest(options) {   return (req, res, next) => {     const { body } = req;     const { required } = options;     const errors = {};      if (required && required.length) {       required.foreach(key => {         const value = `${body[key]}`;          if (_.isempty(value)) {           errors[key] = 'this field required';         }       });     }      if (!_.isempty(errors)) {       res.send({ success: false, errors });     } else {       next();     }   } } 

then can used so:

routes/auth.js

router.post('/login', validaterequest({   required: ['identifier', 'password'] }), auth.login); 

Comments