I'm attempting to implement form validation on a new Contact in my app using the ember-validations library. I'm currently using Ember Data with fixtures, and I've opted to place the validations in the model like the example in this video. I've been grappling with this for days now, and still can't seem to figure out why the validations aren't working. I'm not getting any indication that errors are even firing.
//app/models/contact.js
import DS from "ember-data";
import EmberValidations from 'ember-validations';
//define the Contact model
var Contact = DS.Model.extend(EmberValidations, {
firstName: DS.attr('string'),
lastName: DS.attr('string'),
});
//Create Contact fixtures
Contact.reopenClass({
FIXTURES: [...]
});
Contact.reopen({
validations: {
firstName: {
presence: true,
length: { minimum: 2 }
},
lastName: {
presence: true
}
}
});
export default Contact;
I'm new to Ember, and have been advised to put the following logic in routes instead of the controller. I haven't seen any examples of this being done with ember-validations, so I'm unsure if that's my issue regarding validations.
app/routes/contacts/new.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.createRecord('contact');
},
actions: {
createContact: function() {
var contact = this.get('currentModel');
this.transitionTo('contacts');
contact.save();
alert(contact.errors);
},
cancelContact: function() {
var contact = this.get('currentModel');
contact.destroyRecord();
this.transitionTo('contacts');
}
}
});
My other suspicion is that I may not be handling the errors in html correctly?
//app/templates/contacts/new.hbs
{{#link-to 'contacts' class="btn btn-primary"}}Contacts{{/link-to}}
<form>
<label>First Name:</label>
{{input type="text" value=model.firstName}}<br>
<span class="error"></span>
<label>Last Name:</label>
{{input type="text" value=model.lastName}}<br>
<span class="error"></span>
</form>
<button {{action "createContact"}} class="btn btn-primary">Submit</button>
<button {{action "cancelContact"}} class="btn btn-warning">Cancel</button>
<br>
Here is my controller
//app/controllers/contacts.js
import Ember from "ember";
export default Ember.Controller.extend({
});
I'm enjoying Ember, but this issue is stonewalling me greatly. Any help would be much appreciated.
I'm going through this exact thing and have some advice. First I would say validate where you need to ask something if it is valid. You might need to do this on the component if it's a form, you might need to do this on a model if you want to ensure it's valid before saving, or maybe on a route if there are properties there that you're wanting to check.
In any case whatever method you pick, I would highly recommend using the ember-cp-validations
addon. For what it's worth, Stephen Penner (ember.js core team) has contributed to the addon, too. It's all ready for Ember CLI as well.
The setup is actually very similar to what you're doing, but instead of reopening the class, you would define with it a mixin (example from their docs). To create the mixin that's used they have a factory called buildValidations
. The nice thing is that you can use this on any Ember object.
Once you've defined your validation and mixed it into the create of your object, ie: Ember.Object.create(Validations, {});
where Validations
is the mixin you've created just above (like in the docs). You are all set.
Within scope of that object you now have a validations
property on the object, so something like:
var Validations = buildValidations({
greeting: validator('presence', true)
});
export default Ember.Object.create(Validations, {
greeting: 'Hello World',
actions: {
announce: function() {
alert('The current validation is: ' + this.get('validations.isValid'));
// per property validation is at:
alert('The individual validation is: ' + this.get('validations.attrs.greeting.isValid'));
}
}
})
Handlebars:
Looks like the form is {{ validations.isValid }}.
You can also <a {{action announce}}>announce the validation</a>.
Also, take a look at all the docs, there are is even more properties and use cases that this addon takes care of, including handlebars helpers, ajax/async resolution of validation, and some validators to use. If you don't find the one you're after make a function
validator. Using the function
validator all over, easy, make it re-usable with ember generate validator unique-username
.
Hope this gets you off in the right start. This is a relatively new project but has decent support and responses on the issues has been quick.
Should also mention that because these validations are based on computed properties they work in an "Ember way" that should work great, including your models.