I am having trouble using the default()
sanitizer from express-validator. When I use it in a chain, such as body("children").optional().isArray().default([])
, the default
function doesn't do anything, resulting in children
being undefined
. However, if I separate these into two different statements (adding a separate body("children").default([])
sanitizer instead of chaining it with the others), it works perfectly fine. Here is a minimal reproducable example...
import express from "express";
import { body } from "express-validator";
const app = express();
app.use(express.json());
app.post(
"/fails",
body("children").isArray().optional().default([]),
(req: express.Request) => {
console.log(`/fails output: ${JSON.stringify(req.body, null, 4)}`);
}
);
app.post(
"/works",
body("children").isArray().optional(),
body("children").default([]),
(req: express.Request) => {
console.log(`/works output: ${JSON.stringify(req.body, null, 4)}`);
}
);
app.listen(3000);
...that, used with these libraries...
@types/express@4.17.12
express-validator@6.12.0
express@4.17.1
typescript@4.3.4
...gives this output:
/fails output: {}
/works output: {
"children": []
}
Both POST
requests had an empty body (I am using Postman to test this).
Why is this happening? I have tried juggling the optional
, isArray
, and default
checks around, with no result. Even though /works
, well, works, I don't want to duplicate the same body
statement twice for each optional default value I have in my schema.
Does anyone know how to fix this problem?
When removing .optional()
from the chain, it works. So this code:
import express from "express";
import { body } from "express-validator";
const app = express();
app.use(express.json());
app.post(
"/fails",
body("children").isArray().default([]),
(req: express.Request) => {
console.log(`/fails output: ${JSON.stringify(req.body, null, 4)}`);
}
);
app.post(
"/works",
body("children").isArray().optional(),
body("children").default([]),
(req: express.Request) => {
console.log(`/works output: ${JSON.stringify(req.body, null, 4)}`);
}
);
app.listen(3000);
Gives the correct output for both /fails
and /works
. However, I have no idea why this happens! Why can't I do .optional().default([])
? Why isn't this documented? I created a bug report on GitHub here if anyone is interested.