'How can I create localized message in Joi from context?

Here is the scenario of what I want to achieve:

  1. User input data is validated in frontend using Joi.
  2. Data is validated in backend, also using Joi.
  3. Potential validation errors are returned to frontend, which can handle those since the same validation framework is being used.

In the frontend, we have translated messages for some errors, and fallbacks to Joi default messages for the rest. In the backend, we have no translations.

My problems come when I'm trying to recreate the error message. How can I:

1) Access a "template string"

In the Joi library each value type has it's own set of template messages:

const messages = {
    // ...
    'string.min': '{{#label}} length must be at least {{#limit}} characters long',
    // ...
};

I can't find out how to access these in an easy way. And I also want to add translated messages, and use these before falling back to the default ones. Is there anything like Joi.getTemplate('string.min')?

2) Recreate the error message

When I get the array with Joi errors from the backend, I want to recreate the error messages, localized if available. The errors look like this:

"details": [
  {
      "message": "\"name\" length must be at least 10 characters long",
      "path": [
          "name"
      ],
      "type": "string.min",
      "context": {
          "limit": 10,
          "value": "Joe",
          "label": "name",
          "key": "name"
      }
  }
]

Is there some way of doing something like this: Joi.generateMessageFromTemplate('string.any', details[0].context) or Joi.generateMessage('{{#label}} length must be at least {{#limit}} characters long', details[0].context)

I also need to load the translated message before I do that, in some way.

My feeling is that there should be ways to achieve what I want, but I can't find in the documentation (or the source code) exactly how I should proceed. Please help me :)



Solution 1:[1]

 const Joi = require('joi').defaults(schema => schema.options({ messages: {
 ar:{
'string.empty': '?? ???? ?? ???? ???? {{#label}}',
'number.base': '??? ?? ???? ??? {{#label}}',
'any.invalid': '???? ??? ????? {{#label}}',
'phoneNumber.invalid': '??? ??? ???? {{#label}}',
'array.unique': '???? ?????? {{#label}}',
 },
 en:{
'string.empty': '{{#error}} Cannot be empty',
'number.base': '{{#label}} Must be a number',
'any.invalid': '{{#label}} Value not valid',
'phoneNumber.invalid': 'Phone Number not valid',
'array.unique': '{{#label}} contains a duplicate value',
 }
} }));

and on validate you can select your prefered language like so:

const result = yourSchema.validate({mydatafield:"val"}, {
    errors:{language: 'ar'} //en or ar
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ghyath Darwish