1

What is the best technique to cache Angular Scope from last browser session to a newly loaded one?

Is that possible?

Including to control the next time to create a cache of the complete scope?

And override the loaded cached scope, when new data is loaded from the back-end?

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
AHJ
  • 153
  • 1
  • 16
  • Cache `$scope` or some data inside `$scope`? – Saravana Jul 26 '16 at 17:00
  • Only data inside the Scope and areas inside the Scope. – AHJ Jul 26 '16 at 17:03
  • If your objective is sharing data on the scope across your app, you need to use services. "Angular services are substitutable objects that are wired together using dependency injection (DI). You can use services to organize and share code across your app." https://docs.angularjs.org/guide/services – pro Jul 26 '16 at 17:12

1 Answers1

3

This is more related to how to cache data in the browser using javascript.

There are some solutions you can look into for angular specifically:

Angular services can be used to share the scope between routes within the same session. But if you close the browser, you'll need one of local/session storage, cookies, or a server-side solution.

$cookies

Cookies is a straightforward key-value storage. Easy to use for a quick way to save data.

angular.module('cookiesExample', ['ngCookies'])
.controller('ExampleController', ['$cookies', function($cookies) {
    // Retrieving a cookie
    var favoriteCookie = $cookies.get('myFavorite');
    // Setting a cookie
    $cookies.put('myFavorite', 'oatmeal');
}]);

Don't use cookies to store extensive data and limit this to data which should be sent on every request, like a authentication token.

ngStorage

An AngularJS module that makes Web Storage working in the Angular Way. Contains two services: $localStorage and $sessionStorage.

bower install ngstorage

Pass $localStorage (or $sessionStorage) by reference to a hook under $scope in plain ol' JavaScript:

$scope.$storage = $localStorage;

And use it like you-already-know:

<body ng-controller="Ctrl">
    <button ng-click="$storage.counter = $storage.counter + 1">{{$storage.counter}}</button>
</body>

Optionally, specify default values using the $default() method:

$scope.$storage = $localStorage.$default({
    counter: 42
});

With this setup, changes will be automatically sync'd between $scope.$storage, $localStorage, and localStorage - even across different browser tabs!

local storage demo

The angular-local-storage module provides multiple ways to store your data. It's feature rich and provides advanced options and customisation.

window.angular.module('demoModule', ['LocalStorageModule'])
    .config(function(localStorageServiceProvider) {
        localStorageServiceProvider.setPrefix('demoPrefix');
        // localStorageServiceProvider.setStorageCookieDomain('example.com');
        // localStorageServiceProvider.setStorageType('sessionStorage');
    })
    .controller('DemoCtrl',
        function($scope, localStorageService) {
            $scope.localStorageDemo = localStorageService.get('localStorageDemo');

            $scope.$watch('localStorageDemo', function(value) {
                localStorageService.set('localStorageDemo', value);
                $scope.localStorageDemoValue = localStorageService.get('localStorageDemo');
            });

            $scope.storageType = 'Local storage';

            if (localStorageService.getStorageType().indexOf('session') >= 0) {
                $scope.storageType = 'Session storage';
            }

            if (!localStorageService.isSupported) {
                $scope.storageType = 'Cookie';
            }

            $scope.$watch(function() {
                return localStorageService.get('localStorageDemo');
            }, function(value) {
                $scope.localStorageDemo = value;
            });

            $scope.clearAll = localStorageService.clearAll;
        }
    );

Additional information

Community
  • 1
  • 1
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
  • Don't use cookies. It will create awful behavior problems when you open multiple tabs or try to support browser history actions like the back button or share links. So will local storage. Cookies and local storage are *browser wide* while you're almost certainly looking for per-tab-session persistent behavior between "pages". Angular is incredible naive about this aspect of design. It's Cold Fusion for millennials. – Michael Mikowski Mar 26 '17 at 06:22
  • `$rootScope` can be used for per-tab-session persistent behavior. Cookies have another potentially big downside: they get sent with every Ajax request. This can make your application slower and less secure. – Michael Mikowski Mar 26 '17 at 13:13
  • @MichaelMikowski `$rootScope` won't even persist a page refresh... local storage and cookies should be used to save data on the client side, like a auth token. – Emile Bergeron Mar 26 '17 at 14:56
  • @MichaelMikowski OP specifically mentioned **"cache Angular Scope from last browser session to a newly loaded one"**, there's no doubt about what he was looking for and though a lot of question on AngularJS are about sharing data between pages (controllers), this one isn't. – Emile Bergeron Mar 26 '17 at 15:02
  • @EmileBergeron having written web applications for 25 years, I certainly know when to use a cookie, and using it for local storage is a hack that has outlived its useful life. That's what local storage for. Real developers don't even need a framework and extra library to type `localStorage.setItem('this', 'that');` and `localeStorage.getItem('this')`. Your other point is correct; however, I let the comment stand because I have seen numerous Angular apps using Cookies where $rootScope should be used instead and felt it may be useful to some. – Michael Mikowski Mar 26 '17 at 19:53
  • @MichaelMikowski we don't know which data OP wants to store, so we can't say if cookies or local storage are good or not for his use-case. About the framework, I would say the opposite, where a good developer will use a **properly tested lib with additional features** and will avoid reinventing the wheel. – Emile Bergeron Mar 27 '17 at 12:53
  • @EmileBergeron "...where a good developer will use a properly tested lib with additional features and will avoid reinventing the wheel". Indeed, why bother using a perfectly good, simple, native capability supported on all modern browsers when you can insert an ill-conceived and bloated abstraction layer? – Michael Mikowski May 23 '17 at 03:15
  • @MichaelMikowski with that mindset, even Angular is useless... And I wouldn't call the [cookie API](https://developer.mozilla.org/en-US/docs/Web/API/document/cookie) simple. – Emile Bergeron May 23 '17 at 15:15
  • @EmileBergeron The cookie API is a red herring as it is useful in this capacity only in extreme edge cases,With the alternate mindset we'd use angualar, typescript, bootstrap, ES6, Babble, Grunt, and Sass to write hello world. Sometimes we work far too hard at being lazy. https://mmikowski.github.io/no-frameworks/ And yes, Angular is a steaming mess. – Michael Mikowski May 23 '17 at 22:11