Caveat: I’m working with a backend that I don’t have full control over, so I’m wrestling with a few considerations within Backbone that might be better addressed elsewhere…unfortunately, I have no choice but to handle them here!
So, my problem is that I’d really like to validate user input from a form (when I set values with it on Backbone models), but the models I receive from the API on newly created objects (via posts that ONLY accept a name, and ONLY return a name and object id) will fail my validation checks.
As example, when a new object is created in the database, two key fields are populated as empty strings (and so when Backbone hits the API and populates the models, it populates those keys with empty strings). When the user saves these objects back, post-edit, I’d like to force them to enter values for these two keys — which is very easy, given Backbone’s built in validation method.
The problem, of course, is that the validation is firing on both fetch->set (unwanted behavior) and set->save (desired behavior) — and so newly created models won’t load at all…Backbone collects them, validation fails, and errors fire.
So, my question is: is there a “Backbone-y” way to only validate the models on set->save, not on fetch->set? Could I use a specific trigger to work around this?
Any ideas would be greatly appreciated.
Backbone.Model.setwon’t perform validation if you pass in{ silent: true }, andfetchwill pass any options through to set, so you could either overridefetchor write your ownfetchSilentmethod that passes that in an options object.However, you might run into a slight gotcha with
Backbone.Collection.fetch, because when it receives attributes from the server, it doesn’t create the new models withset. Instead, it creates a new model withmodel = new this.model(attrs, {collection: this});and then performs validation if there’s avalidatemethod on the object.This is a little annoying. You can get around it by defining a
parsemethod on your collection (if you’re using one) that creates a model silently (using{silent: true}), because whenBackbone.Collection.addreceives a fully formed Backbone model, it won’t run the validation. (see the_addand_prepareModelmethods in the annotated source).It’s a little annoying that the collection works that way, but (for now at least) it is what it is.