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.

Editing and Validating Forms with ember-changeset

Subscribe to our mailing list