Search code examples
javascriptnode.jsvalidationexpressjoi

How to add custom validator function in Joi?


I have Joi schema and want to add a custom validator for validating data which isn't possible with default Joi validators.

Currently, I'm using the version 16.1.7 of Joi

const method = (value, helpers) => {
  // for example if the username value is (something) then it will throw an 
  // error with the following message but it throws an error inside (value) 
  // object without error message. It should throw error inside the (error) 
  // object with a proper error message
        
  if (value === "something") {
    return new Error("something is not allowed as username");
  }

  return value; // Return the value unchanged
};
        
const createProfileSchema = Joi.object().keys({
  username: Joi.string()
    .required()
    .trim()
    .empty()
    .min(5)
    .max(20)
    .lowercase()
    .custom(method, "custom validation")
});
        
const { error, value } = createProfileSchema.validate({
  username: "something" 
});
        
console.log(value); // returns {username: Error}
console.log(error); // returns undefined

But I couldn't implement it the right way. I read Joi documents but it seems a little bit confusing to me. Can anyone help me to figure it out?


Solution

  • Your custom method must be like this:

    const method = (value, helpers) => {
      // for example if the username value is (something) then it will throw an 
      // error with the following message but it throws an error inside (value) 
      // object without error message. It should throw error inside the (error) 
      // object with a proper error message
    
      if (value === "something") {
        return helpers.error("any.invalid");
      }
    
      return value; // Return the value unchanged
    };
    

    Docs:

    https://github.com/hapijs/joi/blob/master/API.md#anycustommethod-description

    Output for value :

    { username: 'something' }
    

    Output for error:

    [Error [ValidationError]: "username" contains an invalid value] {
      _original: { username: 'something' },
      details: [
        {
          message: '"username" contains an invalid value',
          path: [Array],
          type: 'any.invalid',
          context: [Object]
        }
      ]
    }