Parris
Parris

Reputation: 18438

How can I do a single attribute set in Backbone.js (validation)

Yesterday, after researching quite a bit I found that if I want to not set individual attributes on my backbone model (and have validation) then I need to send {silent: true}. That being said we also found out that in the next release of backbone.js silent: true will actually still run validate.

The problem with this is that validate blocks set from actually setting the attributes. So if we don't have silent:true then there is no point of having a set method that accepts single attributes. To work around this our validate method looks something like this:

validate : function(attrs) {
    var errors = {};
    if (typeof attrs.first_name !== 'undefined' && !attrs.first_name) {
        errors.first_name = "First name can't be empty";
    }
    ...
    if (!_.isEmpty(errors)) {
        return errors;
    }
}

This causes save to not work. So then we decided to write something like this:

if (_.isEmpty(attrs)) {
    attrs = this.attributes;
}

The problem with that is if you have attributes sent in on save then you need to merge them in, which I guess is ok, but this is all a decent amount of work to get some simple validation to work/or not run. Furthermore unless I override _validate I need to do it on every model.

Is there a better way to do this?

Upvotes: 1

Views: 174

Answers (1)

Simon Boudrias
Simon Boudrias

Reputation: 44629

Backbone by default extends the old attributes with the old ones here: https://github.com/documentcloud/backbone/blob/master/backbone.js#L574

As so, only new attributes could break the validation method.

Here, I think your problem is that you tie too much of your validation to the presence of all attributes, while you're not setting them all at the same time. As so, you should make sure the other attributes are allowed to be set as undefined.

example:

// Check if name is set, ignore otherwise
if( attr.name && attr.name !== "Santa" ) { return "Can't be Santa"; }

Another solution is to give every attribute a valid default value.

Upvotes: 3

Related Questions