validate.js
validate.js copied to clipboard
[WIP] Add array support with any constraints
I implemented forEach validator and forEachSingle validator. We can specify any constraints for each array element.
Why [WIP]?
This pull-request is WIP (work in progress), because I want you to check following:
- Adds validator specification about return value. (Any other ideas to implement array support are welcome)
- Adds multiple words validator name, but current master has only single word validator name. (Maybe you want to change validator name to
foreach) - And other your requests. implementation, validator name, and so on.
After you accept them, I will create tests, git push it and remove [WIP] mark.
forEach validator
This validator checks object properties in array element.
Sample:
validate({
users: [
{id: -1, name: 'foo'},
{id: 1, name: '西田雄也'}
]
}, {
users: {
forEach: {
id: {numericality: {greaterThan: 0}},
name: {format: /^[a-zA-Z0-9]+$/}
}
}
})
//=> {"users[0].id":["Users[0] id must be greater than 0"],"users[1].name":["Users[1] name is invalid"]}
This is following requests implementation:
- https://github.com/ansman/validate.js/issues/1#issuecomment-153413241
- https://github.com/ansman/validate.js/issues/104
I think this validator name is forEach and it is better than each. I thought following:
- Currently validate.js has
forEachKeyInKeypath. - ECMAScript 2016 uses
forEach(Array.prototype.forEach), and it doesn't useeach. http://www.ecma-international.org/ecma-262/7.0/#sec-array.prototype.foreach
forEachSingle validator
This validator checks object in array element like validateSingle function.
Sample:
validate({ary: ['foo', '', 'tooLongString']}, {
ary: {
forEachSingle: {
presence: true,
length: {
maximum: 3
}
}
}
})
//=> {"ary[1]":["Ary[1] can't be blank"],"ary[2]":["Ary[2] is too long (maximum is 3 characters)"]}
Coverage decreased (-6.4%) to 93.603% when pulling 098d4440779b241df2b19c30e014a883283ffe5d on nishidayuya:add_array_support into ab5ad5a3a7a82546c7a1aecedb338b6413e20119 on ansman:master.
Hey guys, when can we expect this to be released? 😃
Is there any update on this?
+1
I think that instead return a object like:
{
'ary[1].name': 'Cant be blank',
'ary[1].somethikng': 'Cant be blank'
}
should be:
{
ary: [
{ name: 'Cant be blank', something: 'Cant be blank' }
]
}
or:
{
ary: {
1: {
name: 'Cant be blank',
something: 'Cant be blank'
}
}
}
What you think?
+1
At first glance, without writing a custom formatter, it looks like the minimum we can do is the following.
length: {
minimum: 1
}
which only checks length and a string would give us a false positive, when we're looking for an array. Is there a widely accepted array formatter pattern that people are using in the meantime?
Something that could validate this kind of pattern:
{
"id": "123",
"notes": [
{
"date": 2015-10-05T12:00:00,
"comments": "monty python"
},
{
"date": 2015-10-06T12:00:00,
"comments": "something else entirely"
}
]
}
definitely looking forward to this PR! thanks :)
edit: example custom validator to validate all values in an array for example above
custom validator:
validate.validators.arrayValidator = function(value, options) {
if (!Array.isArray(value))
return 'must be an array';
value.forEach(function(obj) {
validate(obj, options);
});
};
schema:
notes: {
length: {
minimum: 1
},
arrayValidator: {
date: {
datetime: true
},
comments: {
length: {
minimum: 10
}
}
},
presence: true
I'm so sorry. This PR slipped through the cracks it seems, it looks like a good first implementation. If you add some tests I'll try to get it merged ASAP.
@ansman Any update on when this will be released? Thank you.
+1
This would be pretty cool
Its some way how works with var constraints = {} like with array
I have trouble, when is in {} some element which not exists, code does not work
Original:
var constraints = { "addresses.shipping": { presence: true }, "addresses.shipping.street": { format: { // Must be numbers followed by a name pattern: "^[0-9]+ .+$", message: "^The street for the shipping address must be a valid street name" } } };
Will be like: ` var constraints = {};
// dont care about "exists()"
if(exists("addresses.shipping")){
constraints.push(
"addresses.shipping": {
presence: true
}
);
}
// dont care about "exists()"
if(exists("addresses.shipping.street")){
constraints.push(
"addresses.shipping.street": {
format: {
// Must be numbers followed by a name
pattern: "^[0-9]+ .+$",
message: "^The street for the shipping address must be a valid street name"
}
}
);
}
`
@nishidayuya resolve merge conflicts when you have time :D
any update on when this will be released?
+1 when can we expect this?
I worked around this for now, but it would be great to have this baked in.