In EmberData calling model.save()
causes the model to be persisted via whatever adapter is in place. If the adapter returns some data (such as JSON from an API) the model is updated with that data.
I have stumbled upon a sequence where this is not true.
In a voucher system for a checkout process a voucherCode
is entered on an order
model. When an 'Apply' button is pressed the order is saved via order.save()
and the voucher is thus submitted to the server.
If the voucher code is valid a voucherValue
field is populated with a number. If the voucher code is invalid a 422
error is returned with a standard errors
object as per http://ift.tt/1kd5W52
Now, here is where things go awry. If a code is entered that returns a voucherValue
of 300
a controller property calculates the discount.
discount: function () {
var discount = this.get('model.voucherValue');
// some calculation
return discount;
}.property('model.voucherValue')
If, for whatever reason, the user then enters an invalid code we return an error as described above. The server removes the discount and sets the voucherValue
to 0
As the error response does not contain the updated data in the catch
of the save
we manually update it.
order.save().then(function () {
}).catch(function (error) {
order.set('voucherValue', 0);
});
The discount
computed property
is updated as expected on setting the voucherValue
. However, inspecting the order model shows that order._data.voucherValue
is still the original 300
value from the first valid voucher code - as EmberData does not know this value is persisted on the server.
If we then enter a valid voucher code that returns a voucherValue
of 300
(the same as it was originally) the discount
computed property is not recalculated.
It appears Ember is checking the returned data values against order._data
and as there is no difference is not triggering any property recalculations.
I've tried different workarounds but have been unable to find something that works reliably.
Frustratingly there does not seem to be a reliable way to access the returned data and manually set the voucherValue
from the returned data. Even if the returned data sets a value for voucherValue
the following is true:
order.save().then(function (savedOrder) {
savedOrder.get('voucherValue') === 0; //true
}).catch(function (error) {
order.set('voucherValue', 0);
});
However, if a different voucher is entered after an invalid voucher and the voucherValue
is different (say 450
) everything works as expected.
Is this a bug in EmberData? Is there a know workaround. I'm open to suggestions and willing to try anything before I try and reengineer how this entire system is implemented.
Aucun commentaire:
Enregistrer un commentaire