Cache and set area value in angular.js

I have a multi-tab application with two separate controllers.

When one tab is entered, I need to click on the API. The answer is not updated after the first press, so there is no need to hit it again on subsequent visits to this tab.

My question is what is the proper way to cache an API response and set it to a scope variable.

I currently have a help function similar to this

var setAndCache = function(scope, cacheFactory, cacheKey, cacheValue) { scope[cacheKey] = cacheValue; cacheFactory.put(cacheKey, cacheValue); }; 

Factory cache setting so

 factory('TabData', function($cacheFactory) { return $cacheFactory('tabData'); }). 

which is entered into each controller

 controller('TabOne', function($scope, $http, TabData) { var setupCache = function(response) { setAndCache($scope, TabData, 'tabOneData', response); }; if (!TabData.get('tabOneData')) { $http.get('/path/to/api') .success(function(response) { setupCache(response); }); } else { setupCache(TabData.get('tabOneData')); } 

It works great, but it feels ... dirty. Is there a better way to achieve the same?

+4
source share
1 answer

I myself worked through resource caching. This is how I do it so far.

I start with the cacheManager service:

 app.factory('cacheManager', function($cacheFactory) { var cache = $cacheFactory('resource'); return { /** * This will handle caching individual resource records * @param CacheId string where we expect this to be stored in the cache * @param Resource resource The resource object that we want to get * @param Object param An object of params to pass to resource.get * @param Function callback * @return resource object */ fetchResource: function(cacheId, resource, params, callback) { var result = cache.get(cacheId); // See if we had a valid record from cache if(result) { console.log("cache hit: " + cacheId); callback(result); return result; } else { console.log("cache miss: " + cacheId); result = resource.get(params, function(response) { if(response.error) { // We don't have a valid resource, just execute the callback callback(response); return false; } console.log("putting resource in cache"); cache.put(cacheId, response); callback(response); }); return result; } }, <snip update/delete methods, etc> 

Then in my controller, I add both the cacheManager service and my project resource (for example), and then I can:

 $scope.data = cacheManager.fetchResource('project.' + $scope.id, Project, {id: $scope.id}, function(response) { ... }); 

I love how clean this keeps my controllers.

I know that in your case you are using $ http directly, not a resource, but the same approach can be used. I personally would recommend abstracting the logic in the cache wrapper service as much as possible and minimizing the overhead in each of your controllers.

Update:

As mentioned in the comment below, it’s much easier to use resource caching that you should pay attention to. First, I started with this example, and then created it in what I am using above.

angularjs: how to add caching to a resource object?

+3
source

All Articles