$cacheFactory deletes my cache when page reloads - angularjs

So I have a simple factory that creates cache object
.factory('jsonCache',function($cacheFactory){
console.log("Creating cache");
return $cacheFactory('weatherCache');
});
I'm then calling that cache object inside my controller like so by passing it in like so. But for some reason the data is not persistent. Every time I reload the page, the cache is empty again.
Any ideas? Did I miss something?
.controller('citiesListCtrl',function($scope,$http,$filter,jsonCache){
jsonCache.get('weatherCache');
console.log(jsonCache); <----- EMPTY
$http.get(url)
.then(function(response) {
jsonCache.put('weatherCache', response.data.records);
console.log(jsonCache); <--- HAS DATA
});
)}

The data is not persistent for very good reason: $cacheFactory cache is nothing but a thin wrapper around plain JS object.
You can check the source to make sure that the service does nothing but simple LRU algorithm.
For data persistence use persistent storage (probably angular-local-storage or angular-localForage). angular-cache is an another replacement for built-in $cacheFactory that supports persistence.

Related

Store JSON file contents on load

Right now, I have a factory which loads a JSON file.
angular.module("app").factory("RolesFactory", ['$http', '$q', function($http, $q) {
var d = $q.defer();
$http.get('events.json').success(function(data) {
d.resolve(data);
});
return d.promise;
}]);
And then I call this factory when I need the contents of events.json with this controller:
App.controller('rolesCtrl', ['$scope', 'RolesFactory', function($scope, RolesFactory) {
RolesFactory.then(function(roleData){
$scope.roles = roleData.roles;
});
}]);
All good, but whenever I need to use this data. Isn't it refetching the contents of events.json? Meaning: is Angular reloading the file over and over again? I was hoping to load the file once and call it by a global variable or something.
When my app loads initially, I want it to load and store the contens of events.json -- and then I'd like my app to be able to use this data whenever/wherever.
Is this possible?
As AngularJS is a stateless framework, you have only a few options here, all of which are some kind of client-side caching:
Use localStorage to store your data. Once the data is fetched, you can just save it to localStorage using localStorage.setItem after Stringifying the JSON. You'll need to re-parse the JSON the next time you use it though, so if this is a giant JSON, this is not the best idea
Use sessionStorage to store your data. This is exactly the same as #1, but you will lose data upon termination of session,i.e. closing your browser.
Trust the JSON to be cached in your browser. This is most likely the case. Static assets are by default cached by most modern browsers. So, the second time your factory requests the JSON, the resource isn't actually fetched from the server. It is merely pulled from the browser's cache.
NOTE: The way to check this is to see what the HTTP status code for your resource is, in Chrome's Developer Tools Network tab. If the status says 304 that means it has been pulled from cache.

Angular default $http cache removes after route change

I am using Angular's default $http cache in one of my services. When the user navigates from a view to another one (I am using ui-router), the cache invalidates and all of the items will be removed from it. I want to not invalidate the cache in the whole lifetime of my application.
EDIT:
For example, this factory does not return cached result after navigating to another route and it calls the server api to get the result:
cardModule.factory("myFactory", function ($http) {
return {
getAll: function () {
return $http.get("all", { cache: true })
}
}
});
How to prevent default cache from removing items from itself after a route change?
I found the source of the problem. It was my own fault. I had a code somewhere that clears the cache after the state change. There is no problem with default angular $http cache.
I would leave this as a comment but I don't have enough points yet..
Could you try some form of memoisation? In other words, have a model on the scope, then, if the model is undefined, trigger the $http call? Something like:
var ctrl = this;
ctrl.product = undefined; // or null
if (ctrl.product === undefined) { // or null
$http.get(...).then(function(resp) {
ctrl.product = resp.data;
};
};
This way the model gets initialized, and called just once. A possible downside would be that the if statement may make this inefficient.
I have not tested this, just throwing the idea out there. I am also very interested in this problem.
That should not be related to ui-router or $http. Here are a few things you need to confirm:
Is your server (which is serving your resources) is setting the cache header or not
Make sure you are not using Ctrl + F5 to refresh the page
If you are using Chrome browser, make sure a setting Disable cache is unchecked

Caching an Angular App

What's the best way to cache things in Angular when you use ui-router? The problem is when switching between views it does all the $http requests again which is a bit pointless. Options I came up with or read about:
1) Just store everything to $rootScope.
Pro: Quickly implemented;
Con: Gets messy with too many objects (globals...)
2) Make a cache service
angular.module('myApp')
.factory('Cache', function($cacheFactory) {
var cache = $cacheFactory('Cache');
return cache;
});
To me this is the same as $rootScope since with Cache.put("someObject", obj); is pretty much the same as $rootScope.someObject = obj?
3) Cache via $http
$http.get(url, { cache: true}).success(...);
Pro: Doesn't use globals.
Con: Needs to be cleared when retrieved object is changed by user. Probably only good for kind of static content.
4) Make a service for every cached object
Are there other options? I find none of those above really satisfying...

angularjs, ngResource in a factory and network calls

Trying to get my head around this. I have a simple factory using ngResouce, like this:
.factory('FooResource', function($resource) {
var foo = $resource('/api/foo').get();
return foo;
})
And in my app, in multiple places, in multiple controllers over time, I use the value of 'FooResource.bar' (where 'bar' is returned in the data from the get() call).
Is it true that the network call to '/api/foo' will only happen on the first reference for the life of my SPA? Does that first reference need to 'FooResource.bar' be handled like a promise?
From what I see in my playing around with code, it seems like the first question is 'yes' and the second is 'no', but don't know if that's really true in general, or just happening because its a small test app on my dev box.
Edit: I guess part of what I want validation on is my thinking that since this is in a factory, which is a singelton, the $resource call will only ever be made once. Is that true?
Depends, and yes. You will always need to handle it as a promise, and you can enable/disable the http cache. If you have the cache set to true, then the request will send off once and be cached until the cache is cleared.
You can find more about the $resource caching in the $resource documentation here: https://docs.angularjs.org/api/ngResource/service/$resource

angularjs cacheFactory is empty

I store some keys in cache using angularJs cachefactory
myApp.factory('SomeCache', function ($cacheFactory) {
return $cacheFactory('someCache', {
capacity: 10 // optional - turns the cache into LRU cache
});
});
in the code :
SomeCache.put(key, value);
I see all the keys and values in the console.
The problem is , when i redirect to another page, not in my webSite ( e.c www.ebay.com)
and the i come back the cache object is empty,
I needd to preserve the data on the page.
Any idea ?
ishay
The behaviour you see with $cacheFactory is expected. The AngularJS-Cache does not persist between page refreshes. See also: Angularjs: date expiration for $cacheFactory
What you need to use to persist data between page refreshes is localStorage or sessionStorage as explained on this site: DOM Storage guide
You should use the excellent ngStorage module.

Resources