Search code examples
javascriptjoi

How to compare two fields in joi?


I try to do validation between two fields. foo and bar.

  1. Both should be a string but they optional. if they have some value it should be min of 2 and max of 10.
  2. If both are empty (""/null/undefined) the validation should be failed and return error.

I try to do it with

.when("bar", { is: (v) => !!v, then: Joi.string().required() }),

But doesn't work the error return undefined.

Any idea how to solve that?

codesandbox.io

const Joi = require("joi");

console.clear();

const schema = Joi.object({
  foo: Joi.string()
    .allow("", null)
    .optional()
    .min(2)
    .max(10)
    .when("bar", {
      is: (v) => !!v,
      then: Joi.string().required()
    }),
  bar: Joi.string().allow("", null).optional().min(2).max(10)
});

const { error } = schema.validate(
  { foo: null, bar: null },
  { allowUnknown: true, abortEarly: false }
);

const { error: error2 } = schema.validate(
  { foo: null, bar: "text" },
  { allowUnknown: true, abortEarly: false }
);

console.log({ error }); // should be with error.
console.log({ error2 }); // should be undefiend.

if (error) {
  const { details } = error;
  console.log({ details });
}

if (error2) {
  const { details } = error2;
  console.log({ details });
}

Solution

  • This how you need to configure to achieve that

    1. empty(['', null]), considers '' and null as undefined.
    2. or("foo", "bar"), makes one of them is required.

    const schema = Joi.object({
      foo: Joi.string().empty(['', null]).min(2).max(10),
      bar: Joi.string().empty(['', null]).min(2).max(10)
    }).or("foo", "bar");