Reputation: 891
I have a server that works with a header ETag. Backbone refers to the API for the first time: everything is good, the response received and parse. Second time: backbone sends to the server ETag, in response receives NotModified. And Backbone trying to parse this response, resulting in a collection called reset.
Is there any way around it resets the collection?
The method of adding the option to add in the fetch method will not work. Since I need to completely refresh the collection, if I came to the server's response.
var recommendCollection = Backbone.Collection.extend({
model : Event,
etag : null,
urlRoot : '/api/users',
initialize: function() {
this.etag = null;
},
parse: function(response) {
return response.data;
},
url : function () {
return (this.urlRoot + "/"+window.me.get('id')+ "/recommendation");
},
beforeSend : function (jqXHR, settings) {
jqXHR.setRequestHeader('if-none-match', this.etag);
},
complete : function (jqXHR, textStatus) {
if (jqXHR.status == 200 || jqXHR.status == 304) {
this.etag = jqXHR.getResponseHeader('ETag');
}
},
update : function () {
this.fetch({
beforeSend : this.beforeSend.bind(this),
complete : this.complete.bind(this),
data : {
cityId : window.me.get('cityId'),
}
});
}
Upvotes: 5
Views: 3539
Reputation: 33364
As far as I can tell, there is no easy solution to trap a 304 response. What I came up with:
parse
receives a second argument, options
, that you can use to check the status of the request and repopulate your collection with the same models if necessary. It works, but it will trigger a reset
parse: function(response, options) {
if (options.xhr.status === 304)
return this.models
return response.data;
}
jQuery accepts an ifModified
option that may help you
ifModified Default: false
Allow the request to be successful only if the response has changed since the last request. This is done by checking the Last-Modified header. Default value is false, ignoring the header. In jQuery 1.4 this technique also checks the 'etag' specified by the server to catch unmodified data.
Or override the fetch
function to stop on a 304 response
fetch: function(options) {
options = options ? _.clone(options) : {};
if (options.parse === undefined) options.parse = true;
var collection = this;
var success = options.success;
options.success = function(resp, status, xhr) {
if (xhr.status!==304)
collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
if (success) success(collection, resp);
};
options.error = Backbone.wrapError(options.error, collection, options);
return (this.sync || Backbone.sync).call(this, 'read', this, options);
}
Upvotes: 8
Reputation: 4669
The 304 response MUST NOT contain a message-body. Sorry, was too hurry answering, my words don't help here.
Upvotes: 1