How to validate array of objects using Joi?

node.jsValidationExpressJoi

node.js Problem Overview


I am getting an array of objects to backend, where each object contains a service name. The structure looks like below

[{"serviceName":"service1"},{"serviceName":"service2"},..]

when I get the array at backend, I want to validate that every object in the array has serviceName property.

I had written the following code, but even though I pass valid array, I am getting validation error.

var Joi = require('joi');
var service = Joi.object().keys({
  serviceName: Joi.string().required()
});

var services = Joi.array().ordered(service);

var test = Joi.validate([{serviceName:'service1'},{serviceName:'service2'}],services)

For the above code, I am always getting the validation error with message

"value" at position 1 fails because array must contain at most 1 items

node.js Solutions


Solution 1 - node.js

replacing ordered with items will work.

let Joi = require('joi')
let service = Joi.object().keys({
  serviceName: Joi.string().required(),
})

let services = Joi.array().items(service)

let test = Joi.validate(
  [{ serviceName: 'service1' }, { serviceName: 'service2' }],
  services,
)

For reference click here

Solution 2 - node.js

A basic/ clearer example is as follows. To validate a JSON request like this:

   {
    "data": [
			{
        "keyword":"test",
        "country_code":"de",
        "language":"de",
        "depth":1
			}
		]
    }

Here is the Joi validation:

 seoPostBody: {
    body: {
      data: Joi.array()
        .items({
          keyword: Joi.string()
            .required(),
          country_code: Joi.string()
            .required(),
          language: Joi.string()
            .required(),
          depth: Joi.number()
            .required(),
        }),
    },
  };

This is what I am doing in NodeJs, might need some slight changes for other platforms

Solution 3 - node.js

Just want to make it more clear. I'm currently using "@hapi/joi:16.1.7".

Let's say you want your schema to validate this array of objects.

const example = [
   {
      "foo": "bar",
      "num": 1,
      "is_active": true,
   }
];

Then schema's rules should be:

var validator = require('@hapi/joi');

const rules = validator.array().items(
    validator.object(
        foo: validator.string().required(),
        num: validator.number().required(),
        is_active: validator.boolean().required(),
    ),
);

const { error } = rules.validate(example);

Solution 4 - node.js

const test = {
body: Joi.array()
    .items({
        x: Joi.string().required(),
        y: Joi.string().required(),
        z: Joi.string().required(),
        date: Joi.string().required(),
    })

};

Solution 5 - node.js

For Joi you can use below which is working fine for me, this will validate that array must have at-least on object with key serviceName-

const Joi = require('joi');
const itemsArray = Joi.array().items(
            Joi.object({
                serviceName: Joi.string().required(),
            })
        ).min(1).required();

        const itemSchema = Joi.array().items(itemsArray).when('checkout_type', {
            is: 'guest',
            then: Joi.array().required(),
        }).required();

let schema = Joi.object().keys({
        items: Joi.alternatives().try(itemsArray, itemSchema).required(),
    });

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionzakirView Question on Stackoverflow
Solution 1 - node.jszakirView Answer on Stackoverflow
Solution 2 - node.jssediq khanView Answer on Stackoverflow
Solution 3 - node.jsHim HahView Answer on Stackoverflow
Solution 4 - node.jsrajiv patelView Answer on Stackoverflow
Solution 5 - node.jsPrashantAjaniView Answer on Stackoverflow