Is it possible to get messages returned by express-validator into a language other than english for internationalization (i18n) ?
I tried looking into the source code and I could not find it.
Thanks
It's probably something you have to create yourself, but it shouldn't be too hard.
When you assign an error message with withMessage()
you can send more than just a single string. You can for example send an object. So you can put the error messages, for all the languages, for a particular error, in an object.
Here is an example:
Route:
const countValidation = require('./count.validation');
router
.route('/blogposts')
.get(
countValidation.count,
blogpostController.blogpostsGetAll,
);
Validator (in a separate file called count.validation.js):
const message = {
english: 'count must be between 1 and 1000',
chinese: 'count must be between 1 and 1000, but in chinese',
};
module.exports.count = [
check('count')
.optional()
.isInt({ min: 1, max: 1000 })
.withMessage(message)
];
This response will be sent when validation fails:
{
"errors": {
"count": {
"location": "query",
"param": "count",
"value": "-1",
"msg": {
"english": "count must be between 1 and 1000",
"chinese": "count must be between 1 and 1000, but in chinese"
}
}
}
}
In this particular example the front-end has to choose what error message to display depending on user settings or user agent.
It's also possible to deal with what error message to use on the server side, if we know what language the client is using from the request. We could for example read the accept-language header in the request. Here is an example of how that could be done:
The controller function:
Rather than using this (standard handling of errors, almost straight from the readme):
module.exports.blogpostsGetAll = (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.mapped() });
}
// The rest of the function...
};
we use this:
module.exports.blogpostsGetAll = (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
const errorsInProperLanguage = handleLanguages(req.headers, errors.mapped());
return res.status(422).json({ errors: errorsInProperLanguage });
}
// The rest of the function...
};
Example function to only use one language:
function handleLanguages(headers, errorsMapped) {
const language = headers['accept-language'].split(',')[0];
for (let errorKey in errorsMapped) {
errorsMapped[errorKey].msg = errorsMapped[errorKey].msg[language];
}
return errorsMapped;
}
Because the accept-language header contains language codes, not language names, we have to modify the message object slightly:
const message = {
'en-US': 'count must be between 1 and 1000',
'zh-CH': 'count must be between 1 and 1000, but in chinese',
};
The message object HAS to contain the first language code in the accept-language header for this to work. The handleLanguage function doesn't handle errors. It's only an example to show how it could be done; don't use it directly.
The error message would change to
{
"errors": {
"count": {
"location": "query",
"param": "count",
"value": "-1",
"msg": "count must be between 1 and 1000, but in chinese"
}
}
}
when the first language in accept-language is zh-CH.