Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialScott Tolan
1,621 PointsAngular forEach Function and Local Storage
Hi,
Would really appreciate it if someone could help me with this problem.
I am trying to develop a Angular Web App that is similar to a check-list with a count function, so basically a user will get a list of football grounds and check off which ones they have visited, and then the count will go down. However at the minute it doesn't save whether the user has checked a ground off when the page has been refreshed or closed down (which is expected) however I am trying to achieve this.
So, I have got as far as adding the grounds into an array, which I can see in Chrome's developer tools, however I am struggling when wanting to firstly find out if the user has checked any grounds off previously through Local Storage, then showing the previously checked boxes. Hope this makes sense!
Does anyone know how this can be achieved or point me in a good direction? Be much appreciated!
Current code:
angular.module('trackerApp', [])
.controller('TrackerController', ['$scope','$http', function ($scope,$http) {
$http.get("grounds.json").success(function(data)
{
$scope.grounds = data;
localStorage.setItem("grounds", JSON.stringify(data));
});
$scope.remaining = function() {
var visited=[]
angular.forEach($scope.grounds,function(ground){
if (ground.done) {
visited.push(ground);
}
})
console.log(visited);
//put the array into localStorage
//retrieve array
var count = 0;
angular.forEach($scope.grounds, function(check) {
//console.log(check.done)
count += check.done ? 0 : 1;
});
return count;
};
}]);
<!doctype html>
<!-- trackerApp module running on all page -->
<html ng-app="trackerApp">
<head>
<script src="angular.min.js"></script>
<script src="main.js"></script>
<link rel="stylesheet" href="normalize.css">
<link rel="stylesheet" href="todo.css">
</head>
<body>
<h1>Football Ground Tracker</h1>
<!-- Tracker controller scope -->
<div ng-controller="TrackerController">
<!-- remaining/grounds/club object can be accessed in this TrackerController because it's on the scope in the todo.js file -->
<span>{{remaining()}} of {{grounds.length}} remaining</span>
<ul>
<li ng-repeat="check in grounds | orderBy: ['league','club'] "><!-- loop over variable check and grounds then order by league followed by club -->
<input type="checkbox" ng-model="check.done"><!-- the ng-model directive represents the data binding process to the function check.done in main.js -->
<span class="done-{{check.done}}">{{check.club}} - {{check.grounds}}</span>
</li>
</ul>
</div>
</body>
</html>
Cheers in advance
Scott Tolan
1,621 PointsAhhh, never realised that. Cheers!
Greg Kaleka
39,021 PointsNo problem. Check out the Markdown Cheatsheet link that shows up when you're making a comment (just below the textarea).
Good luck with your app! I have no idea how to store things in Angular. I'd probably use PHP to save a sessionID array that held state values like this...
2 Answers
Andrew Kiernan
26,892 PointsHey Scott:
If you add an ng-change
directive to your checkbox input, you can set up a method to fire whenever someone checks or unchecks a checkbox. I set it to a saveGrounds
method that simply saves the grounds items to localStorage.
The HTML:
<input type="checkbox" ng-model="check.done" ng-change="saveGrounds()">
And the controller method:
$scope.saveGrounds = function () {
localStorage.setItem('grounds', JSON.stringify($scope.grounds));
};
From there you can make your initial data call ($http.get) into an if/else statement to check localStorage:
if (localStorage.getItem('grounds')) {
$scope.grounds = JSON.parse(localStorage.getItem('grounds'));
} else {
$http.get("grounds.json").success(function(data) {
$scope.grounds = data;
localStorage.setItem("grounds", JSON.stringify(data));
});
}
That should allow your app to keep the count of visited and remaining grounds.
Let me know if you have any questions!
-Andrew
Scott Tolan
1,621 PointsThanks for that mate, got it working exactly how I wanted! Never realised the Ng-Change directive existed, and that it would make such light work of something like this.
Thanks again, really appreciate that.
Scott Tolan
1,621 PointsHi Andrew,
Thanks for the help last time!
Just a further question if possible, I've tried to dynamically adjust the application by creating a menu so the user can navigate between each page this works fine and as wanted. However because I dynamically load each page by using sessionStorage, would I be able to apply the method you suggested last time to also check if the user has checked off a input box method. I have shared a workspace below if could possibly have a look if you get time.
Much appreciated.
Andrew Kiernan
26,892 PointsHey Scott,
Yeah I don't think there should be an issue using the same method. Sorry I haven't had a chance to look at your app more closely, but one thing you want to be aware of when using sessionStorage and localStorage is that both only store strings. So to store your objects you will want to use JSON.stringify to set them, and JSON.parse to get them, otherwise your get requests will return '[object Object].'
If you run into any issues, just let me know.
Scott Tolan
1,621 PointsHi Andrew, thanks for the reply, the issue I'm running into is that I'm calling the list based on a league ID, so when I applied the method you suggested last time, it bring up the same list no matter what league the user clicks on (hope that makes sense). So is there a way I can adjust the method to call the list of teams based on the league the user clicks on then apply the method to check if the user has previously checked off any teams in that league?
Here is a link to the original application where the method you suggested worked - http://helios.hud.ac.uk/u1170593/version1/index.html
And a link to the new application - http://helios.hud.ac.uk/u1170593/MyApp/index.html#/league
I understand you are probably very busy so any help and advice is much appreciated!
Greg Kaleka
39,021 PointsGreg Kaleka
39,021 PointsHey there - this will be much easier to read if you add ```javascript on the line just before your code.