Retrieving an array of objects from localstorage in angularjs - javascript

I am new to Ionic and AngularJS. I am trying to store an array of objects to local storage. The code below works fine if I only store one object (I am able to retrieve the data). The problem arises when I try to store and access data from an array of objects (prints blank).
Here is my index.html
<ul class="list">
<li class="item" ng-repeat="alarm in alarms">
{{alarm.hour}}: {{alarm.min}} {{alarm.pos}}
<span class="item-toggle">
<label class="toggle toggle-balanced">
<input type="checkbox" ng-model="alarm.on" ng-click="completeTask($index)">
<div class="track">
<div class="handle"></div>
</div>
</label>
</span>
</li>
</ul>
</ion-content>
controller.js
$scope.createalarm = function (alarm) {
$scope.alarms.push({
hour : alarm.hour , min : alarm.min , pos : alarm.pos , on : true
});
window.localStorage['alarms'] = JSON.stringify($scope.alarms);
$scope.setalarm.hide();
};
$scope.getalarms = function (){
$scope.alarms = JSON.parse(window.localStorage['alarms'] || '[]');
};
I validate data stored in local storage using Storage Inspector in Mozilla. This is the result:
Can anyone Help me?

You can use this code to store an array object to local storage:
localStorage.setItem('alarms', JSON.stringify($scope.alarms));
to retrieve the stored values use this:
$scope.alarms = (localStorage.getItem('alarms')!==null) ? JSON.parse(localStorage.getItem('alarms')) : [];

localStorage.getItem('itemName') it's what you are looking for, you need to modify your getalarms function:
$scope.getalarms = function (){
$scope.alarms = JSON.parse(localStorage.getItem('alarms'));
};

The previously set alarms must first retrieved and stored in a variable. Then push the new alarm in this variable and put them back in storage. With this way you can store an array of objects in the storage. If you dont retrieve the currently saved alarms then you will not be able to save more than one alarm in the storage because every new one will overwrite the previous
$scope.createalarm = function (alarm) {
//retrive all alarms that are currently in our localStorage
//if we dont do that every new alarm will overwrite the old one
$scope.alarms = JSON.parse(window.localStorage.getItem('alarms')) || [];
//push the new created alarm
$scope.alarms.push({
hour : alarm.hour , min : alarm.min , pos : alarm.pos , on : true
});
//save the newly created alarm back in the storage
window.localStorage.setItem('alarms', JSON.stringify($scope.alarms));
$scope.setalarm.hide();
$scope.getalarms = function (){
$scope.alarms = JSON.parse(window.localStorage.getItem('alarms'));
};
}

Related

angular dynamic property name in nested ng-repeat

I'm wondering is there any way to add dynamically generated names in nested ng-repeat, for example:
<div ng-repeat="x in JSONfile">
<div ng-repeat="i in x.name">
<span><a ng-href="{{i.link}}">{{i.name}}</a></span>
</div>
</div>
JSONfile: returns some names,
x.name is dynamically generated from the mentioned JSONfile, and it should be used as a plain text like "NAME", if I add NAME instead of i.name I get the json file loaded, but i want it automatically loaded, because I don't know which of the names will come first.
the i.name returns this:
n
a
m
e
not "NAME" as it should..
So, the question is, is there any way to tell angular that i want this dynamically generated value to be looked as I typed it?
PS.
x.name loads a JSON file with some info about a person.
If i type ng-repeat="i in Tom" it will return the json, but with x.name it doesn't work.
Thanks!
EDIT (added json):
var brojVijesti = [ ];
$scope.JSONfile = brojVijesti;
// LNG Json
$http.get("/LEADERBOARDv2/jsons/LNG.php").then(function(response) {
var LNG = response.data.LNG;
$scope.LNG = LNG;
$scope.LNGbroj = LNG.length;
brojVijesti.push({"name":"LNG", "number":LNG.length});
});
// DT JSON
$http.get("/LEADERBOARDv2/jsons/DT.php").then(function (response) {
var DT = response.data.DT;
$scope.DT = DT;
$scope.DTbroj = DT.length;
brojVijesti.push({"name": "DT", "number": DT.length});
});
I believe you want i in x not i in x.name
Edit: You can then use the $parse dependency which will grab the variable of that specific name from $scope.
<div ng-repeat="x in JSONfile">
<div ng-repeat="i in x">
<span><a ng-href="{{i.link}}">{{getVariable(i.name)}}</a></span>
</div>
</div>
JS:
$scope.getVariable = function(variableName) {
//evaluate the variable name in scope's context.
return $parse(variableName)($scope);
}

How do I remove a specific element from local storage array in Angularjs?

Here's my HTML:
<tr ng-repeat="student in students track by $index">
//some code here
<button ng-click="remove(student)">Delete</button>
</td>
</tr>
And here's my .js file code for deleting a student(not from local storage):
$scope.remove = function(student) {
var index = $scope.students.indexOf(student);
$scope.students.splice(index, 1);
}
How do I access local storage from my js code and delete a particular student from local storage.
Sounds like you should rephrase your question to be "How do I access browser's local storage from js code?"
You can access localStorage in your js code with localStorage.
I would delete your student from $scope.students and when finished, set the new array as an item in local storage:
$scope.remove = function(student) {
var index = $scope.students.indexOf(student);
$scope.students.splice(index, 1);
localStorage.setItem('students', JSON.stringify($scope.students));
}

Angular JS - ng-repeat repeating old values

I am new to Angular JS. I have created a code in angular using app and controller. What I am tyring to do is to add name dynamically to a array when a button is clicked.
By default my array has two value passed. When i give an input and click the add button,it adds the string for the first time.
But when i give another input and click add again, the old string is replaced by the new string and the new string is added again.
Here is the piece of code on JSFiddle: http://jsfiddle.net/5DMjt/3680/
var demo= angular.module("demo",[]);
var simplecontroller = function($scope){
$scope.members = [{id:1,name:'prateek'},{id:2,name:'Ruchi'}];
$scope.addmember = function(newmember){
newmember.id = $scope.members.length+1;
$scope.members.push(newmeber);
demo.controller(simplecontroller);
}
}
and here is the HTML Code:
<div ng-app="demo">
<div ng-controller="simplecontroller">
<ul>
<li ng-repeat="member in members">{{member.id}}-{{member.name}}</li>
</ul>
Name<input type="Text" ng-model="inputmember.name">
</br><h2>
{{inputmember}}
</h2>
<input type="button" value="Add" ng-click="addmember(inputmember)">
</div>
</div>
Please Help !
What i analyzed is that push function is passing the address that is why binding still exists.What u can do is pass the value instead like i did below-:
$scope.addmember = function(newmember){
newmember.id = $scope.members.length+1;
$scope.members.push({id:newmember.id,name:newmember.name});
demo.controller(simplecontroller);
}
Hope this solves your problem.Happy learning :)
You have two options.
Either you can reinitialize it every time what I would not recommend.
And the other one is to, pass the parameters with values.
$scope.members.push({id:newmember.id,name:newmember.name});
:)
See this updated fiddle: http://jsfiddle.net/5DMjt/3689/
Name<input type="Text" ng-model="newname">
This gives you a scope variable newname.
<input type="button" value="Add" ng-click="addmember()">
And addmember function uses this newname to create a new object and add it to the list:
$scope.addmember = function(){
var newmember = {};
newmember.id = $scope.members.length+1;
newmember.name = $scope.newname;
$scope.members.push(newmember);
}
You have a syntax error. See console error for more info.
Your variable inputmember is not defined anywhere.
Also you need to push to array new reference of the object, so the old one in array does not change each time you type value.
Here is a working version.
http://jsfiddle.net/a9zvgm8k/
$scope.addmember = function(newMember){
newMember.id = $scope.members.length+1;
$scope.members.push(angular.extend({}, newMember));
demo.controller(simplecontroller);
}
$scope.members = $scope.members.concat({id: newmember.id, name: newmember.name});
Solved : http://jsfiddle.net/5DMjt/3693/
Before pushing to $scope.members you need to create a new object and populate it with id and name from the input.

Binding data into localStorage with ngStorage - what's wrong here?

I started this journey trying to get some settings to persist with localStorage, has some problems and posted about it here (without a solution): Why won't this data bind? An odd case in Angularjs
I've abandoned that method as I learnt about ngStorage. In theory ngStorage lets you 2-way bind into and out of Angular models. It's a great, great theory.
I'm having problems with it though. It half works.
The ideas is this:
Test for permission selection (true or false).
If no selection (first time use) pop-up a choice.
Store the choice.
On restart use the stored choice to set the permission true or false.
Allow user to change the permission from within the app.
It works up to number 4.
Testing shows that although on first use I can set $storage.analytics to true or false subsequent changes are not being stored and retrieved from local storage.
Here is the code:
permissionCallback = function(permission){
if(permission===1){
console.log("analytics allowed");
analytics.startTrackerWithId('UA-45544004-1');
$scope.$storage.analytics=true;
navigator.notification.alert('You can turn analytics off in the Data Tracking section at any time.', null, 'Analytics On', 'OK');
}else{
console.log("analytics denied");
$scope.$storage.analytics=false;
navigator.notification.alert('You can turn analytics on in the Data Tracking section at any time.',null , 'Analytics Off', 'OK');
}
}
if(typeof $scope.$storage.analytics === 'undefined'){
navigator.notification.confirm('This app would like your permission to collect data on how you use the app. No personal or user identifiable data will be collected.', permissionCallback, 'Attention', ['Allow','Deny']);
}
else{
console.log('start analytics are', $scope.$storage.analytics);
if(typeof analytics !== 'undefined'){
console.log("analytics functioning");
analytics.startTrackerWithId('UA-45544004-1');
$scope.trackClick = function(category, action){
analytics.trackEvent(category, action);
console.log('Tracking category: ' + category + ', Section: ' + action + '.');
}
}
}
$scope.counter = 0;
$scope.change = function(){
$scope.counter++;
console.log('analytics are ' + $scope.$storage.analytics);
}
And here is the html.
<li class="item item-toggle">
<i class="icon ion-cloud"></i> Data Tracking is {{$storage.analytics}} {{counter}}
<label class="toggle toggle-balanced">
<input type="checkbox" ng-model="$storage.analytics" ng-change="change()">
<div class="track">
<div class="handle"></div>
</div>
</label>
</li>
It's either a fault with my logic or, and I think this more likely, a misunderstanding about the scope of the data.
The odd thing is the console log in the change() function (which is purely for tracking these things) is always correct. So using $storage.analytics in the html is the correct way to do it (using $scope.storage.analytics causes all sorts of errors) and it is indeed binding from the html into $scope.storage.analytics.
So why isn't it saving it to local storage when using the toggle?
I ran into a similar problem with ng-storage. When the page was loaded/reloaded anything bound to a value in $sessionStorage was updated correctly. However any changes to $sessionStorage afterwards were not reflected in my view. What I ended up doing was creating a service for storing changes and using $sessionStorage as a temporary data store.
app.controller('TestController', funciton($scope, $sessionStorage, Service) {
// if we have session data set our service
if($sessionStorage.data) {
Service.data = $sessionStorage.data;
} else {
$sessionStorage.data = {};
}
// now bind scope to service
scope.data = Service.data;
// on update we set both Service and $sessionStorage
// scope.data will be automatically updated
scope.update = function(val) {
Service.data.value = val;
$sessionStorage.data.value = val;
}
});
app.service('TestService', function() {
var service = {
data: {
value: 'Hello World'
}
};
return service;
});
<div ng-controller="TestController">{{data.value}}</div>
<button ng-click-"update('Hello Universe')">Update</button>
This is a very rudimentary example of how my solution works but hopefully it gets anyone else stuck in the same situation on the right track.

edit update existing array in javascript

I am making CRUD app for learning purpose. I need to update existing javascript array on click of edit button. However currently its not updating the existing array rather then its creating new record. Below is the JS code of controller
For Add screen below is the controller code
.controller('addController', ['$scope','$location','$rootScope', function(scope,location,rootScope){
scope.save = function (){
scope.personName = document.getElementById('name').value;
scope.personDesc = document.getElementById('desc').value;
scope.person = {'name' : scope.personName, 'desc' : scope.personDesc};
if(typeof rootScope.crew === 'undefined'){
rootScope.crew = [];
}
rootScope.crew.push(scope.person);
location.path("/");
}
}])
For Edit Screen, below is the code of controller :-
.controller('editController',['$scope','$location','$routeParams','$rootScope', function(scope,location,routeParams,rootScope){
var oldName = scope.crew[routeParams.id].name;
document.getElementById('name').value = scope.crew[routeParams.id].name;
document.getElementById('desc').value = scope.crew[routeParams.id].desc;
scope.editSave = function(){
scope.person = {
'name' : document.getElementById('name').value,
'desc' : document.getElementById('desc').value
}
rootScope.crew.push(scope.person);
location.path("/");
}
}])
Currently I am adding record in existing array rather updating.
Please suggest
The problem is you are pushing a new item to the array. You need to just update the existing person with the person in scope.
.controller('editController',['$scope','$location','$routeParams','$rootScope', function(scope,location,routeParams,rootScope){
var person = scope.crew[routeParams.id]
scope.person = {
name = person.name,
desc = person.desc
};
scope.editSave = function(){
scope.crew[routeParams.id] = scope.person;
location.path("/");
}
}])
In your edit view you would have this:
<input type="text" id="name" ng-model="person.name"/>
<input type="text" id="desc" ng-model="person.desc"/>
It's also worth mentioning that there is no need to have code such as document.getElementById as angular will handle the model binding for you so you don't have to interact with the dom using javascript.
Every object that you are pushing in array must be identified by some id.So assign one id attribute to the person object that you are pushing.
Now come to the edit.html
<tr ng-repeat="p in person">
{{p.name}}
//In button I am passing id which I used in editing the person object
<button ng-click="edit(p.id)"></button>
</tr>
//In controller
edit(id){
//firstly search for the person which is going to be updated
for(i=0;i<arrayInWhichYouArePushingData.length;i++)
{
if(arrayInWhichYouArePushingData[i].id==id)
{
arrayInWhichYouArePushingData[i]=UpdatedData;
break;
}
}
This is just an algorithm to solve this type of problem.You have to modify little bit.

Categories