Jonas Winkel Jonas Winkel - 5 months ago 12
AngularJS Question

Localstorage doesn't work on my Todo list Angular

I found this localstorage code from another side, but i tried to put it on my own code, which doesn't work. If i refresh my site, i can see the number of the todo list, but the list it self is gone?

How someone explain me, what is wrong? :)

Btw my controller is on my starting body tag:



<main>
<h1>What to do today?</h1>

<div class="container">

<span>{{ remaining() }} of {{ todos.length }} remaining</span>

<form ng-submit="addTodo()">
<input type="text" ng-model="todoInput" placeholder="Add a new todo" required>
<input type="submit" value="Add new list" >
</form>

<ul>
<li ng-repeat="todo in todos">
<input type="checkbox" ng-model="todo.done">
<span ng-bind="todo.todoText"></span>
</li>
</ul>

<button ng-click="remove()">Clear completed</button>

</div>
</main>

<footer>
<div layout="row" layout-align="center center">
<h3>Winkel Design a/s</h3>
</div>
</footer>

<script>
var app = angular.module('TodoApp', []);
app.controller('todoCtrl', function($scope) {
$scope.saved = localStorage.getItem('todos');
$scope.todos = (localStorage.getItem('todos')!==null) ? JSON.parse($scope.saved) : [{todoText:'Clean your room', done:false}];
localStorage.setItem('todos', JSON.stringify($scope.todos));

$scope.addTodo = function() {
$scope.todos.push({todoText:$scope.todoInput, done:false});
$scope.todoInput = "";
localStorage.setItem('todos', JSON.stringify($scope.todos));
};

$scope.remove = function() {
$scope.todos = $scope.todos.filter(function(item){
return !item.done
});
};

$scope.remaining = function() {
var count = 0;
angular.forEach($scope.todos, function(todo){
count+= todo.done ? 0 : 1;
});
return count;
};

$scope.archive = function() {
var oldTodos = $scope.todos;
$scope.todos = [];
angular.forEach(oldTodos, function(todo){
if (!todo.done)
$scope.todos.push(todo);
});
localStorage.setItem('todos', JSON.stringify($scope.todos));
};

});
</script>
</body>

Answer

LIVE DEMO

It seems, your code works fine except ng-repeat directive. I had to add track by $index, and everything works fine now, as far as I can see.

<li ng-repeat="todo in todos track by $index">
    <input type="checkbox" ng-model="todo.done">
    <span ng-bind="todo.todoText"></span>
</li>

From docs:

If you do need to repeat duplicate items, you can substitute the default tracking behavior with your own using the track by expression.

For example, you may track items by the index of each item in the collection, using the special scope property $index:

Also, I recommend you to use angular module, like angular-local-storage, which will fallback to cookies, in case browser doesn't support localStorage API.