In EmberData, calling model.save() forces the model to persist through any adapter. If the adapter returns some data (for example, JSON from the API), the model is updated with this data.
I stumbled upon a sequence where this is not true.
In the voucher system, the order voucherCode is introduced for the voucherCode process. When the "Apply" button is clicked, the order is saved via order.save() , and the voucher is thus sent to the server.
If the voucher code is valid, the voucherValue field voucherValue filled with a number. If the voucher code is not valid, an error 422 returned with the standard errors object, according to http://emberjs.com/api/data/classes/DS.Errors.html
Now, this is where it all went wrong. If you enter code that returns voucherValue of 300 , the controller property calculates the discount.
discount: function () { var discount = this.get('model.voucherValue');
If for any reason the user then enters the wrong code, we return an error as described above. The server removes the discount and sets voucherValue to 0
Since the error response does not contain updated data in catch save , we manually update it.
order.save().then(function () { }).catch(function (error) { order.set('voucherValue', 0); });
discount computed property updated as expected when voucherValue . However, checking the order model shows that order._data.voucherValue is still the original value 300 from the first valid voucher code - since EmberData does not know that this value is stored on the server.
If we then enter a valid voucher code that returns voucherValue of 300 (the same as it was originally) The calculated discount property is not recalculated .
It seems that Ember checks the returned data values ββon order._data , and since there is no difference, this does not cause any recalculation of the properties.
I tried different workarounds but couldn't find something that works reliably.
Unsurprisingly, there is no reliable way to access the returned data and manually set voucherValue from the returned data. Even if the returned data sets a value for voucherValue , this is true:
order.save().then(function (savedOrder) { savedOrder.get('voucherValue') === 0; //true }).catch(function (error) { order.set('voucherValue', 0); });
However, if another voucher is entered after an invalid voucher, and voucherValue is different (for example, 450 ), everything works as expected.
Is this a bug in EmberData? Is there a way around knowledge. I am open to suggestions and am ready to try something before I try and reengineer how this whole system will be implemented.