2
votes

Let's say I have a Backbone model that when fetch() is called (for that specific model, not the entire collection) it gets this from the server:

{ a: "val-1", b: "val-2" }

Later, I call fetch() on the model again, and this time the server returns:

{ b: "val-x", c: "val-y" }

At this point, I would like my model to have this state, because that's the latest state provided by the server:

{ b: "val-x", c: "val-y" }

However, my Backbone model has this state instead:

{ a: "val-1", b: "val-x", c: "val-y" }

How do I fetch() a model in Backbone so that the resulting state is exactly what is returned from the server, and doesn't include old obsolete fields?

2

2 Answers

5
votes

I discovered that one way to get the desired behavior is by adding this parse function to the model in question:

parse: function(resp) {
  for (var key in this.attributes) {
    if (resp[key] === undefined) {
      resp[key] = undefined;
    }
  }

  return resp;
}

If the response from the server lacks an attribute that's in the local model, it explicitly adds that key to the response with an undefined value. This causes fetch() to behave correctly and remove it from the model.

0
votes

If you want fetch to discard your local state and take the server data without merging then use the {reset: true} option.

From the docs: http://backbonejs.org/#Collection-fetch

When the model data returns from the server, it uses set to (intelligently) merge the fetched models, unless you pass {reset: true}, in which case the collection will be (efficiently) reset.