I found a good way to translate errors that return Joi validator. It was a little bit hard to understand by docs so I opened an issue on Github and I understand how to handle it looking the test that they are made.
As you can see in the documentation the validate function is carried out on the schema and accept payload as first parameter and options as second parameter.
errors can also be set among the options to be precise, there is the language key. You must specify in which language you want to receive it.
There are messages key as well. It accepts an object whose keys are the possible values that I will have in errors.language.
import { itErrors, enErrors } from './joiCustomErrors';
const options = {
errors : {
labels: false,
language: localStorage.getItem('i18nextLng')
},
messages: {
it: { ...itErrors },
en: { ...enErrors }
}
};
// in this case I get the language tag from a Localhost.
// my two possible tags are just 'it' and 'en'
const res = mySchema.validate(payload, options);
Values of these keys will be a specific object, that:
- keys is our tag error
- value is the translate. That is the message that validate function will return to us. This is an example:
export const itErrors = {
'string.empty': 'Non può essere vuoto',
'number.base': 'Deve essere un numero',
'any.invalid': 'Valore non valido',
'domain.invalid': 'Dominio non valido',
'email.invalid': 'Email non valida',
'phoneNumber.invalid': 'Numero di telefono non valido',
'array.unique': 'Valore duplicato',
'custom.max11char': 'Massimo 11 caratteri alfanumerici. Iniziare con una lettera'
};
export const enErrors = {
'string.empty': 'Cannot be empty',
'number.base': 'Must be a number',
'any.invalid': 'Value not valid',
'domain.invalid': 'Domain not valid',
'email.invalid': 'Email not valid',
'phoneNumber.invalid': 'Phone Number not valid',
'array.unique': 'contains a duplicate value',
'custom.max11char': 'Maximum 11 alphanumeric characters. Start with a letter'
};
I can get the error tag directly from Joi. It’s the value of type in error.details of validate function result.
Joi puts some presets tags, as in the example you can see string.empty and number.base. Anyway I can create it when I handle the error.
For example when I execute the custom method, so I create a function with two input parameters. In that function I will return helpers.error that need to Joi to understand which error is it. And as parameter the tag we’ve want to associate with. The same tag that we’ll use to do a translate.
Check row 9 of this snippet:
import Joi from 'joi';
import parsePhoneNumber from 'libphonenumber-js';
const isValidPhoneNumber = (phoneNumber, helper) => {
const res = parsePhoneNumber(phoneNumber, 'IT');
if (res !== undefined && res.isValid()){
return phoneNumber;
}
return helper.error('phoneNumber.invalid');
};
const voiceSchema = Joi.object({
'text': Joi.string().required(),
'voice': Joi.string().allow("")
});
export const phoneNumberSchema = Joi.string().custom(isValidPhoneNumber).required();
export const nameSchema = voiceSchema.required();
export const surnameSchema = voiceSchema.required();
export default Joi.object().keys({
'name': nameSchema,
'surname': surnameSchema,
'phoneNumber':phoneNumberSchema
});
Through this pattern Joi will now return the error already translated based on what you have set.
See you next time.
Top comments (4)
Can you plese explain how did you manage to use localStorage?
I am getting an error in this, I am sure I am doing something stupid here but need your help!
Hi, you can interpret it as a simple GET of data. Obviously they must be set first. It's extremely easy, look here: developer.mozilla.org/en-US/docs/W...
Hi, great article! do you have any idea how to also localize date and number format of the error messages?
Any repo with the code of this example? Thank you!