antone king antone king - 5 months ago 23
AngularJS Question

how to Use LocalStorage with Angular

I have created a small application to add data to a list and calculate the total; however, i want to leverage local storage to prevent loosing data on page refresh. This is what I have tried to no avail. Any insight would be awesome!

angular.module('list', [])

.controller('RecordCtrl', function($scope){

// Historical data
$scope.history = [];

// Default data (can be loaded from a database)
$scope.records = [

];

forEach(values in localStorage){
var newValue = JSON.parse(localStorage[values]);
$scope.records.push(newValue);

}
// Total prices
$scope.Totals = function () {
var priceTotal = 0;



angular.forEach($scope.records, function (record) {

priceTotal += (record.price * record.qty);


});

// Return aggregate data
return { price: priceTotal };
};

// Delete data
$scope.Delete = function (index) {
// Remove first / oldest element from history if it reaches maximum capacity of 10 records
if ($scope.history.length === 10)
$scope.history.shift();
// Add deleted record to historical records
$scope.history.push($scope.records[index]);

// Remove from main records (using index)
$scope.records.splice(index, 1);
};

// Reset new data model
$scope.Reset = function () {
$scope.newDescription = '';
$scope.newQty = 0;
$scope.newPrice = 0;
$scope.newComment = '';
};
$scope.Reset();

// Add new data
$scope.Add = function () {
// Do nothing if no state is entered (blank)
if (!$scope.newDescription )
return;

var newHardware = {
description: $scope.newDescription,
qty: $scope.newQty,
price: $scope.newPrice,
comment: $scope.newComment
};
localStorage.setItem("values" + localStorage.length, JSON.stringify(newHardware));

$scope.records.push(newHardware);


/*
// Add to main records
$scope.records.push({
description: $scope.newDescription ,
qty: $scope.newQty,
price: $scope.newPrice,
comment: $scope.newComment
});
*/
// See $Scope.Reset...
$scope.Reset();
};

// Undo action (delete)
$scope.Undo = function () {
// Add last / most recent historical record to the main records
$scope.records.push($scope.history[ $scope.history.length - 1 ]);

// Remove last / most recent historical record
$scope.history.pop();
};


});

Answer

Use $scope.$watchCollection to trigger a save action to local storage.


Online Demo - https://plnkr.co/edit/uEVND2WRIZ61RtRTK5l1?p=preview

html

<body ng-controller="MainCtrl">
  <h1>
    <a class="btn btn-primary" ng-click="add()">add record</a>
    <a class="btn btn-danger" ng-click="clear()">clear</a>
  </h1>
  <pre>{{records | json}}</pre>
</body>

javascript

app.controller('MainCtrl', function($scope, $window) {

  $scope.records = storageGet('records', []);

  $scope.add = function() {

    var record = {
      name: new Date().getTime() // just for the demo
    };

    $scope.records.push(record);
  };

  $scope.clear = function() {
    $scope.records = [];
  };


  $scope.$watchCollection('records', function() {
    storageSet('records', $scope.records);
  }, true);


  function storageSet(key, value) {
    $window.localStorage[key] = angular.toJson(value);
  }

  function storageGet(key, defaultValue) {
    var value = $window.localStorage[key];


    if (value === undefined) {
      return defaultValue;
    }

    return angular.fromJson(value);
  }

});