Reputation: 148
I am passing a token in the request header and based on that I want to change a middleware parameter in the Express JS route.
The current route code:
this.router.post(
"/",
myInfoMiddleware,
this.info.validate("check1"),
this.info.account
);
In the validate(typecheck: string)
, I have a switch case based on which it returns the express-validation
checks.
Validate code:
public validate(typecheck: string) {
switch(typecheck) {
case "check1": {
return check1_validation
}
case "check2": {
return check2_validation
}
}
}
For example, for check1 it returns below express-validator
of type validation chain middleware. And the same applicable for check2 respectively.
export const check1_validation = [
removeEmoji,
check("firstName")
.not()
.isEmpty()
.withMessage("First Name can't be blank")
.isString()
.withMessage("First Name should be String"),
check("lastName")
.not()
.isEmpty()
.withMessage("Last Name can't be blank")
.isString()
.withMessage("Last Name should be String")
];
export const check2_validation = [
removeEmoji,
check("firstName")
.not()
.isEmpty()
.withMessage("First Name can't be blank")
.isString()
.withMessage("First Name should be String"),
check("lastName")
.not()
.isEmpty()
.withMessage("Last Name can't be blank")
.isString()
.withMessage("Last Name should be String"),
check("phone")
.not()
.isEmpty()
.withMessage("phone can't be blank")
.isString()
.withMessage("phone should be String")
];
But I want to make the middleware this.info.validate("check1")
dynamic so that based on request header token condition I can pass either check1 or check2 to validate() and based on that it would verify the express-validation
check.
Upvotes: 1
Views: 157
Reputation: 8752
express-validator
validations are meant to be passed into an express route handler, which is why your attempt didn't work.
In order to configure and conditionally add them from a middleware, you also need to run them manually from the middleware (with .run(req)
, and you need to await promises they return).
So, create a middleware which will extract headers, and then get validations from your method, and then, run validations manually:
try this:
this.router.post(
"/",
myInfoMiddleware,
validationsMiddleware, // run conditional validations middleware
this.info.account
);
// conditional validations middleware
const validationsMiddleware = async (req: Request, res: Response, next: NextFunction) => {
// get token
const token = req.get('token');
if(!token) throw new Error('no token');
// pass token and get validations from the method
const validations = this.info.validate(token);
// now run validations manually
// parallel
// await Promise.allSettled(validations.map((val) => val.run(req)));
// sequentially
for (const validation of validations) {
const result = await validation.run(req);
if (!result.isEmpty()) {
// ..or however you handle the errors..
//return res.status(400).json({ errors: result.array() });
}
}
// need to pass control to next middleware
next();
}
based on:Manually running validations
Upvotes: 0
Reputation: 1
To make this setup dynamic, you can use myInfoMiddleware
to check the token header and call the appropriate validation function dynamically.
// Dynamic middleware function
const dynamicMiddleware = (req, res, next) => {
const token = req.headers['token']; // Get token from request header
// Choose the appropriate validation function based on `token` value
if (token === 'check1') {
return this.info.validate("check1")(req, res, next);
} else if (token === 'check2') {
return this.info.validate("check2")(req, res, next);
} else {
return res.status(400).send('Invalid token');
}
};
// Route definition
this.router.post(
"/",
myInfoMiddleware,
dynamicMiddleware, // We call dynamic middleware here
this.info.account
);
Upvotes: 0