-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rollbackAttributes() not working after more than one 422 error #3677
Comments
I encountered this problem, too. Some debugging reveals that this line is causing the bug: It happens this way: So invalid.exit should not clear _inFlightAttributes in this case. Sorry, i don't know enough about ember data and the side effects of a change like this. So i cannot make a fix and PR myself. |
I'm encountering exactly this problem too. My app uses a modal to edit a model. Click submit and it saves or encounters errors, click cancel and it closes the modal and does Like @akappen, cancelling works fine after 1 validation error, but after the second one it seems to rollback to the state it was after the first validation error, rather than reloading completely. I don't know about the internals either but I seem to have gotten around it by making a function to do it manually: rollbackRecordAttrs() {
this.get("model").eachAttribute((attr) => {
let savedAttr = this.get(`model._internalModel._data.${attr}`);
this.get("model").set(attr, savedAttr);
});
},
actions: {
save() {
this.get("model").save().then(() => {
this.closeModal();
}, () => {
// Empty error function
});
},
cancel() {
this._super();
this.rollbackRecordAttrs();
}
} Another issue is that relationships don't yet rollback either. I did read that that's in the works though. I have found you can get the ids of belongsTo relationships by looking at: let keyName = "nameOfBelongsToRelationship"; // whatever it may be
this.get(`model._internalModel._relationships.initializedRelationships.${keyName}.canonicalMembers.list.firstObject.id`); |
will investigate this weekend |
Any progress on this Bug? For now I fixed it with an initializer changing the RootState like this: import DS from 'ember-data'; export function initialize(/* container, application */) {
} export default { |
Ok, so I looked at it and I think the change suggested by @RobIsHere is the way to go: remove the @RobIsHere do you want to submit a PR with the above mentioned change? I can help with adding a test to catch a regression ... |
I'm having some success with the fix by @RobIsHere, however I encountered something else I think might be worth mentioning, rare though it may be. As I mentioned above my app uses a modal to edit a model. Well we tried to be clever and put 3 buttons on the modal: save, cancel and delete, the idea being you can just do it all from one modal. However, the DB puts a foreign key constraint on deleting the record that still has associated data, and due to business requirements we just need to inform the user with an error that deletion is prohibited while that data exists (so they have to purposefully go and delete the associated data first). We do that with a backend validation in rails and then expect The problem seems to be in the state of the model. The code: actions: {
save() {
this.get('model').save().then(() => {
this.closeModal();
}, () => {});
},
cancel() {
this._super();
this.get('model').rollbackAttributes();
},
deleteResource() {
this.get('model').destroyRecord().then(() => {
this.closeModal();
}, () => {
// no rollbackAttributes() here as that clears the validation error message
});
}
} A problem arises when you press delete, it fails validations, and then you hit save. Since the save button is calling the Another problem occurs when I fail a Save twice, then hit Delete (which fails), then cancel. The next time I open the model, the errors are still there. If I hit delete in that state, I get:
I realise it's mostly our fault, caused by a cumbersome UI, and we actually successfully worked around this by separating the delete and edit modals, but I feel like it is related to the state of the model and so warranted inclusion in this issue. |
👍 Just came across this issue as well. |
Thanks @tchak and everyone else. Will this be backported to 1.13? |
I have cherry-picked this fix to the 1.13 branch. |
Thanks everyone! This is very awesome. 👍 |
I have an API server that performs server side validation of records and responds with the expected 422 status and a body of validation errors. The model correctly parses the validation errors in the body and makes them available on the errors object for display in the template. At this point if the user cancels the edit operation, I rollback the attribute changes to revert the model to the last saved version. This all works as expected.
If the model is saved two or more times with validation errors, each request responds with the same 422 status and validation errors body. If I try to rollback the attribute values at this point the original attributes are not restored!
I attempted to capture this in a test, but I couldn't figure out how to test this 422 error case. If anyone can point me to tests in ember data that exercise the 422 response condition I might be able to use those as a guide.
Instead of having a nice reproducible test, I can walk through the problem in the browser's javascript console. The first example shows proper rollback after a single 422 failure. The second shows a broken rollback after two 422 failures. This behavior happens on all of my models, not just the task model used in the example.
With one 422 response the rollback works:
With more than one 422 response rollback fails to restore the attributes (note at the end that the model's 'data' object still has the original values even though rollback didn't restore them on the model itself):
The 422 response body has this format:
The text was updated successfully, but these errors were encountered: