Series: Editing and Validating Forms with ember-changeset

Introduction to ember-changeset-validations

Published on Aug 19, 2016

Users can sometimes leave out important information, or format it in ways that your program can't understand. Prevent those problems at the source by validating any information that they try to input and letting them know if changes need to be made.

This video covers the minimal viable validation using the ember-changeset-validations library- including configuring the validation, including it in your changeset, displaying the errors to the user, and preventing saving if there are errors.


Links

Code

//validations/monster.js
import { validatePresence, validateNumber } from 'ember-changeset-validations/validators';

export default {
  name: validatePresence(true),
  level: [
    validatePresence(true),
    validateNumber({gte: 1, lte: 99}),
    validateNumber({integer: true})
  ]
}
//controllers/monsters/monster/edit.js
import Ember from 'ember';
import MonsterValidations from '../../../validations/monster';

export default Ember.Controller.extend({
  MonsterValidations,
  actions: {
    save(changeset){
      changeset.validate().then(()=>{
        if(changeset.get("isValid")){
          changeset.save().then(()=>{
            this.transitionToRoute('monsters.monster.show', this.get("model"));
          });
        } else {
          alert('Fix errors before saving')
        }
      })
    }
  }
});
//templates/monsters/monster/edit.hbs
{{monster-form changeset=(changeset model MonsterValidations) save=(action "save") rollback=(action "rollback")}}
//templates/components/monster-form.hbs
<ul>
  {{#each changeset.errors as |errorSet|}}
    {{#each errorSet.validation as |error|}}
      <li>{{error}}</li>
    {{/each}}
  {{/each}}
</ul>

Transcript

In this video, we’re going to set up a minimally viable validation using the ember-changeset-validations library. It will assume that you’ve already set up Ember changeset, but not necessarily that you’ve done the advanced stuff that we’ve covered in the last two videos, just the introductory stuff that we did in the first video on Ember changeset.

First thing we’ll do is we’ll install ember-changeset-validations. Next thing we’ll do is create a validations file. So we’ll create the validations folder and put a monster validation file in there. First thing we’ll do is import some validators from the addon. We’ll import validatePresence and validateNumber. Then we’ll export a hash of validators. So first we’ll define a validator for the name property, and we’re going to validate that it’s present. Then, we’re going to want to add it as a second argument to the changeset helper. So we would want to add something like MonsterValidations, but it’s currently not available on the controller. The good news is we can make it available pretty easily. So first we import it, and then we include it as a property. This will make it available to use in the changeset helper here in the template.

Now we want to use those validations to get it so when we break the validation, we show an error. So to do that, we’ll need to use the errors object on ember-changeset... so to return an array of errors that we can loop through. So we’ll start off by creating a list and then looping through each errorSet in the errors. I use the term errorSet because each one of these can actually hold multiple validation errors for the same key. With that in mind, we’ll actually loop through the validation of each errorSet and use each of those errors as the list item. Then when we go and remove the name, we’ll see this error popping up on the bottom. So that’s awesome. We’ve got one of our properties, the name, validating. Now it’s time to add more validations.

Let’s go ahead and validate for the level. And we’re going to add multiple validations, so we’ll create an array of validators. So first we’ll validatePresence like we did before, and it’ll be a little bit redundant, but we’re just doing it so we can show an array of validators. And then we’re going to validateNumber, and we’re going to validate that it is greater than or equal to 1 and less than or equal to 99, so it can be level 1 through 99. Now we can see that changing the level, it generates validation errors as well, and because we looped through the errors in the .validation as you can see here, then we’re getting both of these on a separate line, which is really, really useful. And of course if we remove this, then the name will come up as well. And if we add a level that is outside of one validation but not the other, then only the one it breaks will show up.

Here’s another interesting property of validators to be aware of. So we can add another option to validateNumber that has to be an integer. And then when we go and change this, we’ll see that when we change it to a non-integer, it removes this error, so it’s only showing one error from that validator at a time. But what we can do if we want both of those to show up at the same time is just use another copy of validateNumber, this one with the integer: true. And then we’ll see that it’ll show both errors at the same time. The user can now see their errors and that’s awesome. But there’s still a problem. So if we change a couple of other things and hit ‘Save’, then the validator is going to fail and nothing will get saved, and we just lost all of our other work. That’s no good. Here’s how we’re going to fix this.

So we’re going to start by calling validate on the changeset and that will return a promise. And once the promise has returned, then we’ll be able to call isValid on our changeset. And then if it is valid, then we can do what we were already doing before which is saving the changeset and then transitioning to the show route. If it’s not valid, then we’ll get up an alert that says Fix errors before saving. So let’s try this. We’re going to try hitting ‘Save’, and yup, it tells us to fix errors before saving. Then we’ll fix the errors and now we can save. I’d call this a big success.

This is the end of this episode. We have our minimally viable validations set up. But it would be even cooler if we could have these validations in line so that you could see them next to the thing that you’re working on. And in the next video, we’re going to show how to do that.

Editing and Validating Forms with ember-changeset

Subscribe to our mailing list