'Validate array of objects in express validator
I am using express validator to validate my fields. But now i have array of 2 or 3 objects, which contains the "userId" and "Hours" fields like below.
[
{
user_id:1,
hours:8
},
{
user_id:2,
hours:7
}
]
Now i need to validate, if any of object property like hours or user_id is empty or not.if empty throw it's error.
Solution 1:[1]
let arr = [
{
user_id:1,
hours:8
},
{
user_id:2,
hours:7
}
]
You can put check like this, note that arr would be the key in the request body. :
check("arr.*.user_id")
.not()
.isEmpty()
check("arr.*.hours")
.not()
.isEmpty()
Solution 2:[2]
I was able to do it with wildcards like this:
app.post('/users', [
body().isArray(),
body('*.user_id', 'user_idfield must be a number').isNumeric(),
body('*.hours', 'annotations field must a number').exists().isNumeric(),
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({errors: errors.array()});
}
return res.status(200).json(req.body)
Solution 3:[3]
You achieve this by accessing the request body:
const { body } = require('express-validator')
body('*.*')
.notEmpty()
Solution 4:[4]
For anyone who wants to validate an array of objects using checkSchema, here's an example where I am validating an array of objects which can have 0 items. You could even do custom validation if you throw a function to do so:
JSON:
{
"employees": [
{
"roleId": 3,
"employeeId": 2,
},
{
"roleId": 5,
"employeeId": 4,
},
]
}
checkSchema:
const customValidator = (async (employees, { req }) => {
// employees will always be an array,
// given the bail property that will make
// the code to never reach the custom validator
// if the isArray validator fails
if(!something) {
throw Error('employee error');
}
// validate at your will here.
return true;
}
checkSchema({
employees: {
isArray: {
bail:true,
options: {
min: 0,
},
},
custom: {
options: customValidator
},
},
"employees.*.roleId": {
isInt: true
},
"employees.*.employeeId": {
isInt: true
}
})
Solution 5:[5]
If you gonna validate the whole body and the body is an array of objects, you may do this by creating middleware chain with validator(1), errors check(2) and useful middleware(2).
import { body, validationResult } from "express-validator";
// we will use lodash method like an example
import { isArray } from "lodash";
app.post(
"/users",
// the second argument "meta" contains whole request and body
body().custom((_unused, meta) => myCustomValidator(meta.req.body)), // (1)
ensureNoErrors, // (2)
doUsefulStuff // (3)
);
Actually that's all: you need to use construction (1) for getting result.
In order to clarify methods implementation:
function myCustomValidator(body) {
if (isArray(body)) {
throw new Error("Body must be an array");
}
// do other checks with the whole body, throw error if something is wrong
return true;
}
function ensureNoErrors(req, res, next) {
// check if validation result contains errors and if so return 400
const errors = validationResult(req);
if (errors.isEmpty()) {
return next();
}
return res.status(400).json({
// return message of the first error like an example
error: errors.array()[0].msg,
});
}
function doUsefulStuff(req, res, next) {
// do some useful stuff with payload
const [user1, user2] = req.body;
}
Link to express-validator documentation.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Kasir Barati |
Solution 2 | |
Solution 3 | Thyago Dias |
Solution 4 | |
Solution 5 | Igor Rybak |