Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XOR validation using Joi-browser

I am using joi-browser 13.4.0. In order to generate error message for each input field I am trying to validate fields using .required() like so:


  config = {
    input1: Joi.string()
      .empty("")
      .required(),
    input2: Joi.string()
      .empty("")
      .required()
  };

  schema = Joi.object(this.config).xor("input1", "input2");

But this example is invalid because when input1 or input2 is set to .required(), .xor() function is being ignored. Is there any other way to implement XOR validation without using .xor() method?

Thanks.

like image 610
TwistedOwl Avatar asked Jul 13 '26 19:07

TwistedOwl


2 Answers

You don't need required() if you're using xor:

config = {
  input1: Joi.string().empty(""),
  input2: Joi.string().empty("")
};

schema = Joi.object(config).xor("input1", "input2");

In fact, using required() like that would never validate. You'd get one of the following error messages:

ValidationError: child "input1" fails because ["input1" is required]

or

ValidationError: "value" contains a conflict between exclusive peers [input1, input2]
like image 87
Danny Buonocore Avatar answered Jul 15 '26 08:07

Danny Buonocore


Use object.length()

Is there any other way to implement XOR validation without using .xor() method?

Yes, you could for example use the object().length() property to limit the keys in an object to 1.

const Joi = require('joi-browser')

const schema = Joi.object().keys({
  input1: Joi.string().empty(''),
  input2: Joi.string().empty('')
}).required().length(1);

const value = {
  input1: "input1",
};

// this will fail
// const value = {};

// this will fail too
// const value = {
//   input1: 'input1',
//   input2: 'input2',
// };

const result = Joi.validate(value, schema);
console.log(JSON.stringify(result.error, null, 2));


Be careful

Don't forget to add required() to the parent object, otherwise it is possible to pass undefined to the validation function!

Without required() on the parent it is possible that a simple undefined will pass the validation:

const Joi = require('joi-browser')

const schema = Joi.object().keys({
  input1: Joi.string().empty(''),
  input2: Joi.string().empty('')
}).length(1); // no required()

const value = undefined; // this will pass validation

const result = Joi.validate(value, schema);
console.log(JSON.stringify(result.error, null, 2));
like image 24
a1300 Avatar answered Jul 15 '26 07:07

a1300