I have a three field form made of a name field, email field and a textarea. I'm using Joi 4.7.0 version along with hapijs. I use the object below validate the input. I receive the data object from an ajax call. When I fill all the three fields with wrong informations I get only the message relative to the first wrong field. Like that:
"{"statusCode":400,"error":"Bad Request","message":"name is not allowed to be empty","validation": {"source":"payload","keys":["data.name"]}}"
validate: { payload: { data: { name: Joi.string().min(3).max(20).required(), email: Joi.string().email().required(), message: Joi.string().min(3).max(1000).required() } } }
For explanation let suppose to not fill the three field. I get only one message error and not the message error of the others fields. Why?
A validation error occurs when you have validation/response checking turned on for one of the questions and the respondent fails to answer the question correctly (for numeric formatting , required response).
Joi can be used for creating schemas (just like we use mongoose for creating NoSQL schemas) and you can use it with plain Javascript objects. It's like a plug n play library and is easy to use. On the other hand, express-validator uses validator. js to validate expressjs routes, and it's mainly built for express.
I'm not integrating with hapi.js, but I noticed that there is a ValidationOptions
object which can be passed along. Inside that object is an abortEarly
option, so this should work:
Joi.validate(request, schema, { abortEarly: false }
This can also be configured as follows:
Joi.object().options({ abortEarly: false }).keys({...});
Check out these type definitions for more ValidationOptions
: https://github.com/DefinitelyTyped/tsd/blob/master/typings/joi/joi.d.ts
It happens because Joi aborts early by default.
abortEarly
- whentrue
, stops validation on the first error, otherwise returns all the errors found. Defaults totrue
.
*EDIT: Configuration has changed in hapi 8.0. You need to add abortEarly: false
to the routes
config:
var server = new Hapi.Server(); server.connection({ host: 'localhost', port: 8000, routes: { validate: { options: { abortEarly: false } } } });
*See the Joi API documentation for more details.
*Also, see validation
under Hapi Route options.
So Joi stops the validation on the first error:
var Hapi = require('hapi'); var Joi = require('joi'); var server = new Hapi.Server('localhost', 8000); server.route({ method: 'GET', path: '/{first}/{second}', config: { validate: { params: { first: Joi.string().max(5), second: Joi.string().max(5) } } }, handler: function (request, reply) { reply('example'); } }); server.start(); server.inject('/invalid/invalid', function (res) { console.log(res.result); });
Outputs:
{ statusCode: 400, error: 'Bad Request', message: 'first length must be less than or equal to 5 characters long', validation: { source: 'params', keys: [ 'first' ] } }
You can however configure Hapi to return all errors. For this, you need to set abortEarly
to false
. You can do this in server configuration:
var server = new Hapi.Server('localhost', 8000, { validation: { abortEarly: false } });
If you run the script now, you get:
{ statusCode: 400, error: 'Bad Request', message: 'first length must be less than or equal to 5 characters long. second length must be less than or equal to 5 characters long', validation: { source: 'params', keys: [ 'first', 'second' ] } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With