Skip to content
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

model.save(data, {wait:true}) stores the new attributes even after a bad response #1223

Closed
halayli opened this issue Apr 14, 2012 · 10 comments
Closed
Labels

Comments

@halayli
Copy link

halayli commented Apr 14, 2012

x = new Backbone.Model();
x.url = '/some_url';
x.save({'field1': 'test'}, {wait: true})

*** save fails with a HTTP 400 response ***

x.toJSON() -> field1: "test"

The fields that failed a save should not exist in the model after a bad response. I'd argue that they shouldn't have made it into the model's attributes before we get a 200 reponse when wait:true is passed.

@vincentbriglia
Copy link

Surely if server-side fails, you should catch the erroneous format client-side early rather than late using validate? secondly assuming you need a trigger to update your UI you should definitely hook into the succes and error option attributes rather than a change event on 'field1' (this is an assumption)

x.validate = function(attrs) {
    if (attrs.field1 === 'test') {
        return "value of field1 may not be 'test'";
    }
}

x.save({
    'field1': 'test'
}, {
    wait: true,
    success: function () { ... },
    error: function () { ... }
})

@halayli
Copy link
Author

halayli commented Apr 16, 2012

@vincentbriglia There are times where you can only verify on the server, and in either case you shouldn't depend on client-side verification as a mechanism for sanitizing input to the server. The purpose of wait:true is to wait for a response back from the server before setting the attributes but Backbone does it regardless of the HTTP response you get back which doesn't sound right.

@jashkenas
Copy link
Owner

This shouldn't be the case -- Backbone only .set's waited attributes onto the model in the success callback. If the success callback isn't triggered by the server response ... then the attributes aren't set.

If you'd like to reopen this ticket, provide a failing test case for the latest Backbone master branch.

@halayli
Copy link
Author

halayli commented Apr 18, 2012

@jashkenas I provided a failing test case in my initial comment. I tried it in the browser's console on backbone's website http://documentcloud.github.com/backbone/ and got the same behavior.

@jashkenas jashkenas reopened this Apr 18, 2012
@jashkenas
Copy link
Owner

Let's start with a reasonable guess -- @braddunbar ... have you looked into this as part of your wait/validate/save refactorings?

@jashkenas
Copy link
Owner

Looking closer ... wait is causing the attributes to be silently set before the server returns a success -- why should that be happening?

@braddunbar
Copy link
Collaborator

It's because of #928. sync uses toJSON to get it's attributes. That means it uses the model's current state. If the attributes aren't set on the model, sync will ignore them.

have you looked into this as part of your wait/validate/save refactorings?

No, I haven't looked at this issue specifically.

@halayli
Copy link
Author

halayli commented Apr 18, 2012

This is exactly what got me confused. https://github.com/documentcloud/backbone/blob/master/backbone.js#L397

I think the reasoning behind it is that sync uses toJSON and that's why they get set.

One way do deal with this probably is to unset the fields on failure using previousAttributes(). But I don't know if that's the cleanest.

@jashkenas
Copy link
Owner

Thanks for reporting this -- we were reverting previous attributes, but missed ones that didn't exist before that you were adding. I've added a clear to the pipeline to flush this for wait:true

@halayli
Copy link
Author

halayli commented Apr 23, 2012

Np! Thanks for the fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants