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'),
}
});
}
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;
}
http://jsfiddle.net/nikoshr/sxv9P/12/
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);
}
http://jsfiddle.net/sxv9P/1/
The 304 response MUST NOT contain a message-body. Sorry, was too hurry answering, my words don't help here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With