This question is also on stackoverflow.
In an ember app, using JSON Api adapter, I have those models :
# subscription.js
import DS from 'ember-data';
export default DS.Model.extend({
userId: DS.attr(),
user: DS.belongsTo('user'),
courseId: DS.attr(),
course: DS.belongsTo('course')
});
#contact.js
import DS from 'ember-data';
export default DS.Model.extend({
fullname: DS.attr(),
phone: DS.attr(),
email: DS.attr(),
user: DS.belongsTo('user'),
});
#user.js
import DS from 'ember-data';
export default DS.Model.extend({
email: DS.attr(),
subscriptions: DS.hasMany('subscription'),
course: DS.hasMany('course'),
contacts: DS.hasMany('contact')
});
Using ember-rapid-form, I have this template :
{{#em-form model=model}}
{{em-input model=model.user label="Email" property="email" canShowErrors=true}}
{{em-select label="Course" property="course" content=courses canShowErrors=true prompt=" " propertyIsModel=true optionLabelPath="name"}}
{{#each model.user.contacts as |contact|}}
<div class='row'>
<div class='col-md-4'>
{{em-input model=contact label="Name" property="fullname" canShowErrors=true}}
</div>
<div class='col-md-4'>
{{em-input model=contact label="Email" property="email" canShowErrors=true}}
</div>
<div class='col-md-4'>
{{em-input model=contact label="Phone" property="phone" canShowErrors=true}}
</div>
</div>
{{/each}}
<a {{action 'addContact' }}>Add contact</a>
{{/em-form}}
And this route :
import Ember from 'ember';
export default Ember.Route.extend({
model() {
var subscription = this.store.createRecord('subscription');
var user = this.store.createRecord('user');
subscription.set('user', user);
return subscription;
},
actions: {
submit: function(token) {
var subscription = this.controller.model;
subscription.get('user').then((user) => {
user.save().then(() => {
subscription.save().then(() => {
user.get('contacts').invoke('save');
this.transitionTo('subscriptions.success');
}, function() {} );
})
})
},
addContact: function() {
var subscription = this.controller.model;
subscription.get('user').then((user) => {
var contact = this.store.createRecord('contact');
user.get('contacts').pushObject(contact);
})
},
}
});
It works but I have problems with my submit
method. First, I think it’s ugly, I don’t like nested then
. Secondly, if there is a failure with a server side validation, it will not continue and trigger other validations. If some models fail, others can be created on the server side.
I did not found any clean solution on the Internet. The best way can be to pass all data in a single xhr call. I tried without success to pass nested attributes on models.
What’s the best way to do this kind of forms?