Series: Editing and Validating Forms with ember-changeset
Custom Validators
Published on Aug 26, 2016
The built-in validators are useful and well-documented, but sometimes you need something unusual.
In this video we build a custom validator- one that limits how fast we can raise the level on our monsters- and give you the knowledge needed to create your own.
Links
Code
//validators/increment.js
export default function validateIncrement(incrementNumber) {
incrementNumber = incrementNumber || 1;
return (key, newValue, oldValue, changes) => {
let isValid = oldValue == newValue || oldValue == newValue - incrementNumber
return isValid || `Must increment by ${incrementNumber}`;
};
}
//validations/monster.js
import incrementValidator from '../validators/increment';
export default {
level: incrementValidator(2)
}
Transcript
When we built our validation file, we did it pretty basic. We pulled in two different types of validators and then we just did a couple of validations with them. There are of course more validators that are available. There is the presence
validator which we already used, the length
validator, the number
validator, we already used some of the options there but there are a lot, and inclusion
, exclusion
, format
, so things like email
and phone
or url
or a custom format, and confirmation
. And that’ll cover probably 90-95% of your use cases. And this documentation is really self-explanatory, so we won’t go over those in detail. But the other 5% of your use cases, you’ll need to create your own validator, and that’s what we’re going to do in this video.
So first we’ll generate a validator and we’ll call it increment
, and what this validator will do is make sure that the next value is either the same or one above the previous value. That’s useful for when we’re leveling up our monsters. We don’t need them to go from Level 3 to Level 38. No when they’re leveling up, they’ll go to Level 4. So we’re going to import this from our validators/increment
file and include it in the level, and then we’re going to define it in that file. This file is just returning a function and this function can take four different arguments. These arguments are pretty self-explanatory. In this use, the key
will be level, the oldValue
is the old value, newValue
is the value that we’re passing in, and then the changes
are all of the changes on the object where this validation is put. So it’ll be the changes for the name
and the level
and anything else that gets changed.
Alright, so we return true
if it is correct, if the validation is good. So here we’ll compare if the oldValue
is equal to the newValue
, or if the oldValue
is equal to the newValue
minus 1
. So first we’ll test out a number that is different than the one it’s supposed to accept, let’s say 5. Well, it gives us an error. The error it gives us is ‘false’. So let’s fix that. So we can do another or and return the error message string. So it’ll be `Must increment by 1’. So now when we try to replace it by 5, it’ll say ‘Must increment by 1’. Pretty good. And we’ll try putting in 4 and excellent, no error messages. Now let’s try putting in 3. And we want it to be able to stay the same. So what’s the problem here? Well, JavaScript is just weird, so we’re going to use the double equals, and when we use the double equals of course it’ll work.
Now what if we wanted to make it so that you could increment it by something other than 1? So let’s say we wanted our levels to only increment by 2. Could we do that? The answer is yes. So we’ll pass in the incrementNumber
, so that’s the argument that we’ve been passing in here to 2, and then we will say incrementNumber
is equal to the one passed in or 1
as a default. And then instead of having a 1
here, we’ll have the incrementNumber
and we’ll update our error message. And we see that working. We’ll see that 5 no longer gives us an error since that’s two more than 3, but 4 is a problem. 3 is still good.
Of course there still are some changes we could make. Let’s go ahead and make an isValid
property so we can separate that out from our error message more easily. And then if we wanted to, we could do things like giving this more options, letting us chose several increments or maybe a range, but that’s left as an exercise to the reader. The important thing is now you know how to create your own validators and include them in your validation files. And that concludes our series on ember-changeset
and ember-changeset-validations
. I’ll see you next time where we start tackling a new subject.