Ratan Kumar
Ratan Kumar

Reputation: 1650

angularjs not caching resource data . ( even after using cacheFactory )

I am trying to cache the response with angularjs but its not happening .

code #1

var app = angular.module("jsonService", ["ngResource"]);

app.factory("JsonFactory", function($resource,$cacheFactory) {
    var cache = $cacheFactory('JsonFactory');

    var url = "myurl?domain=:tabUrl";

    var data = cache.get(url);

    if (data==undefined) {
    var retObj = $resource(url, {}, {
        list: {
            method: "GET",
            cache: true
        }
    });
    data = retObj;
    cache.put(url, data);
    };
    return cache.get(url);
});

code #2

var app = angular.module("jsonService", ["ngResource"]);

app.factory("JsonFactory", function($resource) {

    var url = "myurl?domain=:tabUrl";
    console.log(url);

    var retObj = $resource(url, {}, {
        list: {
            method: "GET",
            cache: true
        }
    });
    return retObj;
});

after both the code i wrote . when looking in to dev tools there always goes a XHR request in Network tab.

obviously : date does not changes . ( that's the whole point of caching )

Upvotes: 0

Views: 3278

Answers (3)

Chickenrice
Chickenrice

Reputation: 5727

$cacheFactory can help you cache the response. Try to implement the "JsonFactory" this way:

app.factory("JsonFactory",function($resource,$cacheFactory){
    $cacheFactory("JsonFactory");
    var url="myurl?domain=:tabUrl";

    return{
      getResponse:function(tabUrl){
        var retObj=$resource(url,{},{list:{method:"GET",cache:true}});
        var response=cache.get(tabUrl);
        //if response is not cached
        if(!response){
          //send GET request to fetch response
          response=retObj.list({tabUrl:tabUrl});
          //add response to cache
          cache.put(tabUrl,response);
        }
        return cache.get(tabUrl);
      }  
    };
});

And use this service in controller:

app.controller("myCtrl",function($scope,$location,JsonFactory){
  $scope.clickCount=0;
  $scope.jsonpTest = function(){    
    $scope.result = JsonFactory.getResponse("myTab");
    $scope.clickCount++;
}
});

HTML:

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular-resource.js"></script>
<script src="js/ngResource.js"></script>
<body ng-app="app">
<div ng-controller="myCtrl">
    <div>Clicked: {{clickCount}}</div>
    <div>Response: {{result}}</div>
    <input type="button" ng-click="jsonpTest()" value="JSONP"/>
</div>
</body>

Screenshot:

enter image description here

[EDIT] for html5 localStorage solution

JSBin Demo

.factory("JsonFactory",function($resource){
  var url="ur/URL/:tabUrl";
  var liveTime=60*1000;  //1 min
  var response = "";

  return{
    getResponse:function(tabUrl){
      var retObj=$resource(url,{},{list:{method:"GET",cache:true}});
      if(('localStorage' in window) && window.localStorage !== null){

      //no cached data
      if(!localStorage[tabUrl] || new Date().getTime()>localStorage[tabUrl+"_expires"])                  {
        console.log("no cache");
        //send GET request to fetch response
        response=retObj.list({tabUrl:tabUrl});

        //add response to cache
        localStorage[tabUrl] = response;
        localStorage[tabUrl+"_expires"] = new Date().getTime()+liveTime;
      }
      //console.log(localStorage.tabUrl.expires+"..."+new Date().getTime());
      return localStorage[tabUrl];
      }
      //client doesn't support local cache, send request to fetch response
      response=retObj.list({tabUrl:tabUrl});

      return response;
    }  
  };
});

Hope this is helpful for you.

Upvotes: 0

Noishe
Noishe

Reputation: 1421

After reading some of your responses, I think that what you are asking, is why does the network tab show a 200 response from your server, while using angular caching.

There are two caches. The first cache is angular's cache. If you see an xhr request in the network tab at all, then that means angular has decided that the url does not exist in its cache, and has asked the browser for a copy of the resource. Furthermore, the browser has looked in it's own cache, and decided that the file in its cache does not exist, or is too old.

Angular's cache is not an offline cache. Every time you refresh the browser page, angular's caching mechanism is reset to empty.

Once you see a request in the network tab, angular has no say in the server response at all. If you're looking for a 304 response from the server, and the server is not providing one, then the problem exists within the server and browser communication, not the client javascript framework.

A 304 response means that the browser has found an old file in its cache and would like the server to validate it. The browser has provided a date, or an etag, and the server has validated the information provided as still valid.

A 200 response means that either the client did not provide any information for the server to validate, or that the information provided has failed validation.

Also, if you use the refresh button in the browser, the browser will send information to the server that is guaranteed to fail (max-age=0), so you will always get a 200 response on a page refresh.

Upvotes: 2

Noishe
Noishe

Reputation: 1421

According to the documentation for the version of angular that you are using, ngResource does not support caching yet.

http://code.angularjs.org/1.0.8/docs/api/ngResource.$resource

If you are unable to upgrade your angular version, you may have luck configuring the http service manually before you use $resource.

I'm not exactly sure of syntax, but something like this:

yourModule.run(function($http)
{
    $http.cache=true;
});

Upvotes: 0

Related Questions