0

I want to cache the resource object which gets returned from service.js so that again and again API is not hit and response time is fast. How can I use it? Tried few samples but couldnt made it work.

My controller.js

app.controller('MyCtrl2', ['$scope', '$rootScope', '$location', 'UserFactory', 'ProductFactory', '$q', 'Reddit', function ($scope, $rootScope, $location, UserFactory, ProductFactory, $q, Reddit) {

  $scope.casualShirts = function () {
    console.log("casualshirts");
    $rootScope.home = ProductFactory.home.query({productcategory: 'Men Casual Shirts'});

    var pagesShown = 1;
    var pageSize = 21;

    $scope.paginationLimit = function(data) {
        //alert("34");
        return pageSize * pagesShown;
    };
    $scope.hasMoreItemsToShow = function() {
        return pagesShown < ($rootScope.home.length / pageSize);
    };
    $scope.showMoreItems = function() {
        pagesShown = pagesShown + 1;
    };
    $location.path('/view2');
}

}]);

my service.js

services.factory('ProductFactory', ['$resource', '$rootScope', '$cacheFactory', function ($resource, $rootScope, $cacheFactory) {
/*alert("I am here service");*/
console.log("casualshirts service");
return  {


    home: $resource('/rest/products/:productcategory', {}, {
        query: {method: 'GET', isArray: true,cache: $cacheFactory, },
        create: {method: 'POST'}
    })
}]);

Also, how can I set the expiry wherein after some time, cache gets refreshed.

A jsfiddle will be a great help. Thanks a to all brilliants out here.

2 Answers 2

4

I think your $resource declaration is a bit off, since the cache property should either be a boolean or a cache ofject created by the $cacheFactory, not the $cacheFactory service itself. From the docs:

cache – {boolean|Cache} – If true, a default $http cache will be used to cache the GET request, otherwise if a cache instance built with $cacheFactory, this cache will be used for caching.

So if you just set it to true, you should get caching working with the default

 home: $resource('/rest/products/:productcategory', {}, {
    query: {method: 'GET', isArray: true, cache: true },
    create: {method: 'POST'}
})

If you decide to use your own cache object rather than the default $http cache, you crate it like this:

var myCache = $cacheFactory('myCache');

Then you can use the myCache.removeAll() method to clear it whenever you like. See https://docs.angularjs.org/api/ng/service/$cacheFactory

Demo

Here is a snippet which demonstrates using a custom cache (myCache) created with the $cacheFactory, and demonstrates that the caching does work as expected.

It's loosely based on your code, but I had to modify it to demonstrate what I wanted to show.

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

app.controller('myCtrl', function($scope, $resource, $cacheFactory, ProductFactory) {
	$scope.products = [];
	var myCache = $cacheFactory.get('myCache');
  
 	$scope.getProducts = function() {
    	ProductFactory.home.query({id: $scope.id})
  						   .$promise.then(function(product) {
                           		$scope.products = product;
                      			$scope.cache = myCache.info();
                      		});
    };
  
    $scope.clearCache = function() {
        myCache.removeAll();
        $scope.cache = myCache.info();
    };
  
  
});


app.factory('ProductFactory', function ($resource, $rootScope, $cacheFactory) {

  var myCache = $cacheFactory('myCache');
  
	return  {
    	home: $resource(
          	'http://jsonplaceholder.typicode.com/photos/', {}, 
          		{
        			query: {method: 'GET', isArray: true,cache: myCache },
        			create: {method: 'POST'}
				}
        	)
    };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-resource.js"></script>

<div ng-app="app" ng-controller="myCtrl">
  
  <p><strong>Hint:</strong> open devtools and look at the network tab as you run this demo.
    You'll see that the request for a specific ID only occurrs once as long as the
    cache is not cleared.</p>
  
  Enter a product ID (1 - 5000): <input ng-model="id">
  <button ng-click="getProducts()">Get Products</button>
  
  <h3>Products:</h3>
  <pre>{{ products }}</pre>
  
  <h3>myCache:</h3>
  <pre>{{ cache }}</h3>
  
  <button ng-click="clearCache()">Clear myCache</button>
  
  
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

I tried with cache: true only and it didnt work, can you help me with a jsfiddle plz??
Okay, I added a snippet which demonstrates what I mean. Study that and see if that helps.
-1

Try using Restangular. It's alternative solution for dealing with REST in Angular and it also solves the problem of cached resource objects.

Sample:

var accountsResource = Restangular.all('accounts')
accountsResource.one('info',42).get();
accountsResource.one('info').getList();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.