I'm learning NodesJS Express. I am using Express-Validator for my testing purposes. Here is my testing program.
const express = require("express");
const app = express();
const port = 5000;
let bodyParser = require("body-parser");
const { body, validationResult } = require("express-validator");
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post(
"/user",
body("username").isEmail(),
body("password").isLength({ min: 5 }),
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
console.log("Login successfully!");
res.send(200);
}
);
app.listen(port, () => {
console.log(`Server is listening on port ${port}`);
});
When I tried to use a post request with the body parameter: { username:test@, password:12345a }, it worked as my expectation. The server will response like this:
The problem happened when I tried to wrap all the logic in the post request handler into a single middleware. When I sent the same post request, it didn't show the error like the example above. That means the two express-validator donot work. Here is my new program.
const express = require("express");
const app = express();
const port = 5000;
let bodyParser = require("body-parser");
const { body, validationResult } = require("express-validator");
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const validateEmailAndPwdlength = (req, res, next) => {
body("username").isEmail(); // the express-validator middleware doesn't work here.
body("password").isLength({ min: 5 }); // the express-validator middleware doesn't work here.
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
console.log("Login successfully!");
res.sendStatus(200);
};
app.post(
"/user",
validateEmailAndPwdlength
);
app.listen(port, () => {
console.log(`Server is listening on port ${port}`);
});
The two express-validator body("username").isEmail() and body("password").isLength({ min: 5 }) are the validation chains. From Express-Validator document, it says that 'The validation chain is a middleware, and it should be passed to an Express route handler'. Why should we place them a Express route handler? If not, how can we call them inside my second example?
Thank you so much for your time!
CodePudding user response:
body("username").isEmail()
evaluates to a function, and if you simply put it as a statement in your validateEmailAndPwdlength
, it has no effect at all. You could invoke the function yourself, as in (simplified)
const validateEmailAndPwdlength = (req, res, next) => {
body("username").isEmail()(req, res, function() {
body("password").isLength({min: 5})(req, res, function() {
const errors = validationResult(req);
...
});
});
}
but that is much longer and less readable (even in this simplified version) than your first version where you follow the express-validator
's advice. It's so much more elegant, what don't you like about it?
Addendum: You can see in the Node.js console that the validation chains are actually functions:
> body("username").isEmail().toString()
'async (req, _res, next) => {\n'
' try {\n'
' await runner.run(req);\n'
' next();\n'
' }\n'
' catch (e) {\n'
' next(e);\n'
' }\n'
' }'