106

trying to validate that an array has zero or more strings in one case and that it has zero or more objects in another , struggling with Joi docs :(

validate: {
    headers: Joi.object({
            'content-type': "application/vnd.api+json",
            accept: "application/vnd.api+json"
    }).options({ allowUnknown: true }),
    payload : Joi.object().keys({
        data : Joi.object().keys({
            type: Joi.any().allow('BY_TEMPLATE').required(),
            attributes: Joi.object({
                to : Joi.string().email().required(),
                templateId : Joi.string().required(),
                categories : Joi.array().items( //trying to validate here that each element is a string),
                variables : Joi.array({
                    //also trying to validate here that each element is an Object with one key and value
                })
            })
        }).required()
    })
}
Willian
  • 3,011
  • 1
  • 15
  • 38
1977
  • 2,580
  • 6
  • 26
  • 37

7 Answers7

251

Joi.array().items() accepts another Joi schema to use against the array elements. So an array of strings is this easy:

Joi.array().items(Joi.string())

Same for an array of objects; just pass an object schema to items():

Joi.array().items(Joi.object({
    // Object schema
}))
cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • 2
    Joi.array().items(Joi.object({ inputA:Joi.string().optional(), inputB:Joi.string().require() })) on these schema inputA is optional and inputB is required but when send the req inputA giving in validated error inputA should not blank – MDF Dec 08 '18 at 06:44
  • @MohammadFaisal I cannot reproduce that error. With that schema, the value `[{ inputB: 'test' }]` passes validation. Double-check your code. Note that `[{ inputA: '', inputB: 'test' }]` does _not_ pass validation -- either pass a non-empty string, or don't pass anything. (A string is required to have at least one character by default, _if it is provided._ So just don't send empty strings!) – cdhowie Dec 10 '18 at 08:12
32

If you want to validate an array of strings in Joi:

Joi.array().items(Joi.string().valid("item1", "item2", "item3", "item4"))

fIwJlxSzApHEZIl
  • 11,861
  • 6
  • 62
  • 71
17

you can try this:

function(data) {
 const Schema = {
   categories: Joi.array().items(Joi.string()),
   variables: Joi.array().items(Joi.object().keys().min(1))
 }
 return Joi.validate(data, Schema)
}

for more details checkout this repo: https://github.com/raysk4ever/nodejs_withMongoRefArray

Ravi Singh
  • 1,049
  • 1
  • 10
  • 25
10

You can also try this way, I have been using it for long time and working fine for me.

If your array is array of objects than use below:

const Joi = require('joi');

let schema = Joi.object().keys({
    items: Joi.array().items(
        Joi.object({
            item_id: Joi.number().required(),
            item_qty: Joi.number().required(),
            item_type_id: Joi.number().required(),
            item_qty: Joi.number().required(),
            base_price: Joi.number().required(),
            actual_price: Joi.number().required(),
        })
    ).required(),
});

let errors = Joi.validate(req.body, schema);

if you array is simple array than:

let schema = Joi.object().keys({
    items: Joi.array().items(
    Joi.number().required()
).min(10).required()});
Willian
  • 3,011
  • 1
  • 15
  • 38
PrashantAjani
  • 376
  • 3
  • 6
3

Joi.array().items(Joi.string().required(), Joi.number().required()); found it here

chavy
  • 841
  • 10
  • 20
3

Validation when we have an array of objects using Joi:

const schema = Joi.array().items(
Joi.object().keys({
  id: Joi.number().required(),
  name: Joi.string().required(),
}));

We could add validations for objects inside an array itself.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Khushal Vyas
  • 316
  • 3
  • 8
0
validate: {
        headers: Joi.object({
                'content-type': "application/vnd.api+json",
                accept: "application/vnd.api+json"
        }).options({ allowUnknown: true }),
        payload : Joi.object().keys({
            data : Joi.object().keys({
                type: Joi.any().allow('BY_TEMPLATE').required(),
                attributes: Joi.object({
                    to : Joi.string().email().required(),
                    templateId : Joi.string().required(),
                    categories : Joi.array().items(Joi.string()),
                    variables : Joi.array().items(Joi.object().keys().max(1))
                })
            }).required()
        })
    }
1977
  • 2,580
  • 6
  • 26
  • 37