AngryJS
AngryJS

Reputation: 955

Caching angular resource object

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.

Upvotes: 0

Views: 1636

Answers (2)

Michael Bromley
Michael Bromley

Reputation: 4822

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>

Upvotes: 4

Artemis
Artemis

Reputation: 4851

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();

Upvotes: -1

Related Questions