It seems pretty straight forward to validate user\'s input in Node.js RESTapi with Joi
.
But the problem is that my app is not written in English. That m
You can use .error(new Error('message')), And its work for me
var schema = Joi.object().keys({
firstName: Joi.string().min(5).max(10).required().error(new Error('Give your error message here for first name')),
lastName: Joi.string().min(5).max(10).required().error(new Error('Give your error message here for last name'))
..
});
Joi.validate(req.body, schema, function(err, value) {
if (err) {
console.log(err.message)
return catched(err.message);
}
});
The best solution I found was :
Create a Middleware for JOI validation
Validator.js - You can create your custom error object
const Joi = require('Joi');
module.exports = schema => (req, res, next) => {
const result = Joi.validate(req.body, schema);
if (result.error) {
return res.status(422).json({
errorCause: result.error.name,
missingParams: result.error.details[0].path,
message: result.error.details[0].message
});
}
next();
};
In the routes or controller pass this middleware function
const joiValidator = require('../utils/validator'); // Wherever you have declare the validator or middlerware
const userSchema = joi.object().keys({
email : joi.string().email().required(),
password : joi.string().required()
});
routes.routes('/').get(joiValidator(userSchema), (req, res) => {
res.status(200).send('Person Check');
});
Joi Version 14.0.0
const SchemaValidation = {
coins: Joi.number()
.required()
.error(() => {
return {
message: 'Coins is required.',
};
}),
challenge_name: Joi.string()
.required()
.error(() => {
return {
message: 'Challenge name is required.',
};
}),
challengeType: Joi.string()
.required()
.error(() => {
return {
message: 'Challenge type is required.',
};
}),
challengeDescription: Joi.string()
.required()
.error(() => {
return {
message: 'Challenge description is required.',
};
}),
};
In errors object you can get, error type and change message according.
Edit:
Make sure you are using @hapi/joi
- https://www.npmjs.com/package/@hapi/joi, version 16 and above.
Original answer:
The current way (I personally find it better) is to use .messages()
(or .prefs({messages})
).
const Joi = require('@hapi/joi');
const joiSchema = Joi.object({
a: Joi.string()
.min(2)
.max(10)
.required()
.messages({
'string.base': `"a" should be a type of 'text'`,
'string.empty': `"a" cannot be an empty field`,
'string.min': `"a" should have a minimum length of {#limit}`,
'any.required': `"a" is a required field`
})
});
const validationResult = joiSchema.validate({ a: 2 }, { abortEarly: false });
console.log(validationResult.error); // expecting ValidationError: "a" should be a type of 'text'
Usage of .errors()
is not recommended just to update default message with custom message.
.prefs({ messages })
is an elaborate way to provide more options as preferences. The other options for prefs are taken directly from options of .validate()
Further read: https://github.com/hapijs/joi/issues/2158
Update 1: I saw that the above explanation did not work out for some folks, so I have put up some code to test yourself. Check it here: https://runkit.com/embed/fnfaq3j0z9l2
Also updated the code snippet shared previously to have details from package inclusion, to usage, to calling the actual validation method.
Update 2: The list of joi error types and their description (for .messages()
- like string.base, array.unique, date.min etc..) is available here.
Solution to add custom messages:
Simply add another chained function to throw error while defining your schema.
In your case
firstName: Joi.string().min(5).max(10).required().error(new Error('I am a custom error and I know it!')),
Rest will remain same.
Solution to use Joi at client side (Your 2nd question)
Joi-Browser is the package which enables usage of the same schema at the client side.
Here is an interesting discussion you can have a look at.
Cheers!
let schema = Joi.object({ foo: Joi.number().min(0).error(() => '"foo" requires a positive number') });
Docs link