Reputation: 434
I have the following models, customer:
App.Customer = DS.Model.extend({
//Other Attributes
area: DS.belongsTo('area', {async: true})
});
and area model -
App.Area = DS.Model.extend({
name: DS.attr('string'),
zip_code: DS.attr('number')
});
And I use an Ember.Select view to show a dropdown of the area a customer is in -
{{view Ember.Select viewName="select_area" content=possible_areas optionValuePath="content.id" optionLabelPath="content.name" value=area.id prompt="No area selected" selectionBinding="selected_area"}}
and the controller which wires up everything together -
App.CustomerController = Ember.ObjectController.extend({
possible_areas: function() {
return this.store.find('area');
}.property(),
selected_area: null,
actions: {
save: function() {
var selected_area_id = this.get('selected_area.id');
console.log(selected_area_id);
var selected_area = this.store.find('area', selected_area_id);
var self = this;
selected_area.then(function(area) {
console.log(area.get('id'));
var updated_customer = self.get('model');
updated_customer.set('area', area );
console.log(new_customer.get('area.id'));
updated_customer.save()
.then(function(customer) {
//success
},
function() {
//failure
});
});
}
}
});
Now here is the weird thing. Upon calling the 'save' action the first time, the line updated_customer.set('area', area );
fails with the error
Uncaught Error: Assertion Failed: Cannot delegate set('id', ) to the 'content' property of object proxy <DS.PromiseObject:ember551>: its 'content' is undefined.
Upon calling 'save' action immediately after that, the save goes through without any error and area of the customer is updated successfully. Although the dropdown shows selected_area to be null.
How do I prevent the first save from erroring out?
I am using ember-data 1.0.0-beta.6.
Upvotes: 2
Views: 1034
Reputation: 4102
Since you have the association defined in your Customer
model, I would remove the selected_area
property from the controller and use ember-data's associations instead. Bind to the "area" association in the Ember.Select
by using the selectionBinding
property.
{{view Ember.Select viewName="select_area"
content=possible_areas
optionValuePath="content.id"
optionLabelPath="content.name"
prompt="No area selected"
selectionBinding="area"}}
This way, the area
attribute will change when the user interacts with the select menu.
This has the added benefit of cleaning up your save
action since we're binding directly to the area
association for the Customer
.
App.CustomerController = Ember.ObjectController.extend({
possible_areas: function() {
return this.store.find('area');
},
actions: {
save: function() {
this.get('model').save().then(this.onDidCreate.bind(this), this.onDidFail.bind(this))
}
onDidCreate: function() {
// Fullfilled callback
}
onDidFail: function() {
// Rejected callback
}
}
});
However, the possible_areas
property won't be populated when the template first renders since this.get('area')
returns a promise. I would wait to render the select until the promise settles. You can do this in the routes model
hook since it waits until promises settle to render the template.
App.CustomerRoute = Ember.Route.extend({
route: function(params) {
return Ember.RSVP.hash({
customer: this.store.find('customer', params.customer_id),
possible_areas: this.store.find('area')
});
},
// Since the route hook returns a hash of (hopefully) settled promises, we
// have to set the model property here, as well as the possible_areas property.
setupController: function(controller, model) {
controller.set('model', model.customer);
controller.set('possible_areas', model.possible_areas);
}
});
Upvotes: 2