backbone.js fetch results cached

25,174

Solution 1

This is a problem on IE usually and backbone has nothing to do with it. You have to go down to the jQuery ajax call and look at the doc. Backbone uses jquery ajax for its sync method. You can do something like this to force ajax call on all browsers:

$.ajaxSetup({ cache: false });

http://api.jquery.com/jQuery.ajaxSetup/

Solution 2

@Julien's recommendation will work, but every AJAX request will hit the server and nothing will be retrieved from the cache.

$.ajaxSetup({ cache: false });

There is another way of doing this. You could pass "cache: false" as an option in the fetch (see code below). The benefit is that fetch(s) that have "cache:false" will always hit the server and the other fetch(s) may retrieve data from the cache. The application I’m currently writing, access data and content asynchronously. Sometimes I want items to be retrieved from cache and sometimes I want to hit the server.

http://documentcloud.github.com/backbone/#Collection-fetch

jQuery.ajax options can also be passed directly as fetch options, so to fetch a specific page of a paginated collection: Documents.fetch({data: {page: 3}})

You can also override the collection's fetch method similar to the this code.

var PlanMembers = Backbone.Collection.extend({
     ...
     fetch: function (options) {
         options = options || {};
         options.cache = false;
         return Backbone.Collection.prototype.fetch.call(this, options);
     }
     ...
})

.

Below I added "cache: false" to the fetch

planMembers.fetch({
            cache: false,  //Hit the server
            success: function () {
                var recoveryTeam = planMembers.select(function (planMember) {
                    return planMember.get("TeamMemberRole") == "RecoveryTeam";
                });

                var otherMembers = planMembers.select(function (planMember) {
                    return planMember.get("TeamMemberRole") == "Other";
                });

                new App.Views.Index({ collection: { name: "Team", members: recoveryTeam }, el: $('#recoveryTeam') });

                new App.Views.Index({ collection: { name: "Team", members: otherMembers }, el: $('#otherTeam') });
            },
            error: function () {
                alert('failure');
                showErrorMessage("Error loading planMembers.");
            }
        });

Solution 3

Another solution is to prevent caching on the server side with HTTP headers

in php

<?php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
?>

or something like this in node.js with express and coffeescript

res.send results,
  "Cache-Control": "no-cache, must-revalidate"
  "Expires": "Sat, 26 Jul 1997 05:00:00 GMT"
Share:
25,174
dagda1
Author by

dagda1

Updated on July 17, 2022

Comments

  • dagda1
    dagda1 almost 2 years

    I am using fetch in the index action of the following backbone.js controller:

    App.Controllers.PlanMembers = Backbone.Controller.extend({
        routes: {
            "": "index"
        },
    
        index: function () {
            var planMembers = new App.Collections.PlanMembers();
    
            planMembers.fetch({
                success: function () {
                    var recoveryTeam = planMembers.select(function (planMember) {
                        return planMember.get("TeamMemberRole") == "RecoveryTeam";
                    });
    
                    var otherMembers = planMembers.select(function (planMember) {
                        return planMember.get("TeamMemberRole") == "Other";
                    });
    
                    new App.Views.Index({ collection: { name: "Team", members: recoveryTeam }, el: $('#recoveryTeam') });
    
                    new App.Views.Index({ collection: { name: "Team", members: otherMembers }, el: $('#otherTeam') });
                },
                error: function () {
                    alert('failure');
                    showErrorMessage("Error loading planMembers.");
                }
            });
        }
    });
    

    The problem is that the results are being cached. It does not pick up database changes. Is there anyway to tell backbone.js not to cache the results?

    I know I could override the url of the collection and append a timestamp but I am looking for something a bit cleaner than that.

  • PålOliver
    PålOliver about 11 years
    Tested this, and in Backbone 0.9.10 the options parameter is null. I ended up doing this: fetch: function (options) { options = options || {}; options.cache = false; return Backbone.Collection.prototype.fetch.call(this, options);}
  • Erik Ahlswede
    Erik Ahlswede over 10 years
    Thanks. Simple and straight forward!
  • Hypnovirus
    Hypnovirus over 9 years
    This answer, with @PålOliver's addition is definitely the way to go. Backbone (and others) and Require help us avoid global dependencies. Being explicit is the best option imo.
  • Wayne Werner
    Wayne Werner about 9 years
    You have saved me so much pain you don't even know.
  • pabo
    pabo over 6 years
    @ErikAhlswede ಠ_ಠ