I am creating a sample todo application in which I can add/remove tasks but when I refresh the page, data is lost. So I decided to use localStorage to save the task lists and retrieve it when page refreshes.
I am able to do the same but I can retrieve the data only as a array list. How can i list tasks one by one stored in my localStorage and display it exactly like how it was before page load?
HTML CODE
<body ng-app="todoApp">
<div ng-controller="addTaskController" data-ng-init="init()">
<div class="container">
<h3>ToDo Application</h3>
<div class="form-group col-md-6">
<form ng-submit="addTask()" class="form-inline">
<input type="text" placeholder="Enter Your Task" ng-model="newTask" class="form-control">
<button type="submit" class="btn btn-primary">Add Task</button>
<div class="taskList">
<ol>
<li ng-repeat="task in tasks track by $index">{{task}} <i style="color:red;margin-left:10px;cursor:pointer;" class="fa fa-times" aria-hidden="true" ng-click="deleteTask()" data-toggle="tooltip" title="Delete Task"></i></li>
<p ng-show="tasks.length==0">No Tasks Available </p>
</ol>
</div>
</form>
</div>
</body>
JS CODE
var todoApp = angular.module('todoApp',[]);
todoApp.controller('addTaskController',function($scope){
$scope.tasks = [];
$scope.addTask = function() { // Function to add a task to list
if($scope.newTask == null) {
alert("Please enter a task");
} else {
$scope.tasks.push($scope.newTask);
localStorage.setItem("storedTasks", JSON.stringify($scope.tasks));
$scope.newTask = null;
}; // add() ends
}
$scope.deleteTask = function() {
$scope.tasks.splice(this.$index, 1);
localStorage.removeItem("storedTasks");
};
$scope.init = function() {
$scope.retrievedData = localStorage.getItem("storedTasks");
if($scope.retrievedData != null) {
$scope.tasks.push($scope.retrievedData);
} else {
tasks.length==0;
}
}
});
Before Page Reload
After Page Reload
How can i fix this
RetrievedData is an array you have to iterate over and push every item to the tasks object. What you are doing now is dumping the whole array into a single task.
if($scope.retrievedData != null){
$scope.retrievedData.forEach(function(item){
$scope.tasks.push(item);
})
}
Since you can only store string in local storage, which you did via JSON.stringify(), you need to undo it via JSON.parse(text[, reviver]) and then iterate over it.
Related
I'm trying to write an App in AngularJS and at some point I update my Data via a Form:
<h3> Anzeige </h3>
<form name="anzeige-form" ng-controller="AnzeigeController as anzCtrl" ng-submit="anzCtrl.getMyOrder()">
<label for="id">Meine Bestellnummer</label><input type="text" required class="form-control" id="id" ng-model="anzCtrl.id" placeholder="0..X" />
<button type="submit" class="btn btn-default">Laden / Aktualisieren</button>
<div class="ausgabe">
Ihre Adresse : {{anzCtrl.myorder.order.address}}
<ul class="list-unstyled anzeige">
<li class="list-item" ng-repeat="pizza in anzCtrl.myorder.order.cart">
<h3>{{pizza.name}}</h3><br/>
<span class="status" ng-if="pizza.status=0">Bestellt</span>
<span class="status" ng-if="pizza.status=1">Im Ofen</span>
<span class="status" ng-if="pizza.status=2">Lieferbereit</span>
<span class="status" ng-if="pizza.status=3">Unterwegs</span>
<span class="status" ng-if="pizza.status=4">Lieferbereit</span>
<div class="progress">
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="{{pizza.status}}" aria-valuemin="0" aria-valuemax="4" style="width: {{pizza.status * 25}}%">
<span class="sr-only">{{pizza.status * 25}}% Abgeschlossen</span>
</div>
</div>
</li>
</ul>
</div>
</form>
The Angular Code looks like this:
.controller('AnzeigeController',function($http){
//$scope.adress = '';
this.id = 21;
//this.myorder = order2;
this.myorder = {};
//$scope.myarray = {};
this.getMyOrder = function(){
$http.get('get_by_id.php',{params:{"id": this.id}}).success(function(datar){
this.myorder = angular.fromJson(datar);
console.log(this.myorder);
})
}
})
My Problem is now, I don't know how to tell Angular that an asynchronous update has occured and my List will Update with the right values. Logging the myorder variable gives me a correct Object in the debugger / console.
I mostly don't understand how to access the data, because the Line {{anzCtrl.myorder.order.address}} doesn't show anything.
I have a major thinking error is my guess.
Pls clarify how to do it correctly.
Best Regards, Marc
The problem is that this no longer refers to the controller model when your promise resolves. You need to create another variable to hold this and then use this other variable when your promise resolves.
.controller('AnzeigeController', function($http) {
var _this = this;
_this.id = 21;
_this.myorder = {};
_this.getMyOrder = function() {
$http.get('get_by_id.php',{params:{"id": _this.id}}).success(function(datar){
_this.myorder = angular.fromJson(datar);
console.log(_this.myorder);
})
}
})
I want to require an input of type file using angularjs without using the attribute required in the HTML code.
My interface is : enter image description here
I want to get an alert after hitting the button submit.
This is what I have done : enter image description here
function DatabaseCtrl($scope, $http, predefineds, locationSearch, queries, database, $window) {
var credentials = {
fileName: ""
};
$scope.credentials = credentials;
$scope.uploadToFolder = function() {
if( $scope.credentials.fileName.length<1 ) {
$window.alert("Please select a file!");
return false;
}
database.uploadToFolder($scope.credentials.fileName, true);
};
The HTML code :
<form role="form" name="frmUploadFolder" ng-submit="uploadToFolder()">
<div class="box">
<h2>
<span ng-show="isUserFile">File directory browser :</span>
<button type="button" ng-show="isUserFile" class="btn btn-default">See file(s)</button>
<button type="button" ng-show="!isUserFile" class="btn btn-default">Upload file(s)</button>
</h2>
<div class="content">
<p>
<label ng-show="isUserFile" >Please specify a file, or a set of files:</label><br>
<input type="file" ng-show="isUserFile" name="datafile" id="fileName" ng-model="credentials.fileName" size="20" required multiple>
<button type="submit" ng-show="isUserFile" class="btn btn-default" >Upload</button><br>
</p>
<div ui-if="!tree.length" class="message">
<p ui-if="!tree.loading">
<span ng-show="!isUserFile">Empty directory</span>
</p>
</div>
</div>
</div>
</form>
The service js :
angular.module('referl.services').factory('database', function($http, channel, $rootScope) {
var database = {
uploadToFolder: function(fileName, navigateOnSuccess) {
var parameters = {
fileName: fileName
};
$http.get("api/database/uploadToFolder", {params: parameters})
.success(function(response) {
if(response.error) {
alert(response.error);
} else {
if (navigateOnSuccess) {
alert("Navigation On Success !");
}
}
});
}
};
Any help please?
For some reason angular does not fully support binding a model element to a file input. The directive approach is generally the accepted work around, but within your controller you can also use document.getElementById("filename") to get a reference to the filename input and grab its value.
I am currently facing a problem, which has to do with views. I am making an app, which allows for users to create polls. When the poll that a user creates is submitted, I call a POST route to store it:
$scope.userVal = Auth.getCurrentUser();
$http.post('/api/users/update' + $scope.userVal._id, {polls: $scope.polls}).success(function(res){
//console.log("res: ", res);
});
Essentially, I get the user info,and use his id to store the new poll in a schema-defined value called polls.
Now, when a user clicks a button, I display the polls that were created via a ng-view:
$scope.pollView= function(){
$scope.userVal2 = Auth.getCurrentUser();
$scope.userVal2 = $scope.userVal2.polls;
$scope.button = true;
};
In the html, I simply iterate over $scope.userVal2. My problem comes when I try to view a newly created poll. The poll does not initially show up, but if I refresh the page, then it shows up. Is there any reason for this? Does this have to do with the async calls?
Any help would be appreciated!
edit:
Controller:
'use strict';
angular.module('voteApp')
.controller('WallCtrl', function ($scope, $http, Auth) {
$scope.items = [];
$scope.title;
$scope.button = false; //set default to the new poll
$scope.polls = [];
$scope.items.push({id:1, upvotes:0, text:""});
$scope.items.push({id:2, upvotes:0, text:""});
$scope.addOptions = function(){
$scope.items.push({id:$scope.items.length +1, upvotes:0, text:""});
};
$scope.process = function(name, values){
$scope.polls.push({title:name, options:values});
$scope.title = ""; //reset the values for the next poll
$scope.items = [];
$scope.items.push({id:1, upvotes:0, text:""});
$scope.items.push({id:2, upvotes:0, text:""});
$scope.userVal = Auth.getCurrentUser();
$http.post('/api/users/update' + $scope.userVal._id, {polls: $scope.polls}).success(function(res){
//console.log("res: ", res);
});
};
$scope.newView= function(){
$scope.button = false;
};
$scope.pollView= function(){
$scope.userVal2 = Auth.getCurrentUser().polls
$scope.button = true;
};
$scope.delete = function(val){
$scope.polls = $scope.polls.filter(function(returnableObjects){
return returnableObjects.title !== val.title;
});
};
});
html:
<div ng-include="'components/navbar/navbar.html'"></div>
<header class="hero-unit" id="banner">
<div class="container">
<h1>Dashboard</h1>
<p class="lead">What would you like to do today?</p>
<button ng-click="newView()" type="button" class="btn btn-lg newpoll">New Poll</button>
<button ng-click="pollView()"type="button" class="btn btn-lg mypolls">My Polls</button>
</div>
</header>
<div ng-show= "!button">
<form name="form" ng-submit="process(title, items)">
<h2 class="col-md-12 text-center">New Poll</h1>
<h5 class="col-md-12 text-center">Name your poll.</h1>
<input name="pollname" ng-model="title"type="text" class="form-control input_width" placeholder="Poll Name" required>
<br>
<h5 class="col-md-12 text-center">Options</h1>
<div ng-repeat="item in items">
<p>
<input name = "{{item.id}}" ng-model="item.text" type="text" class="form-control input_width" placeholder="Option {{item.id}}" required>
</p>
</div>
<br>
<div class="text-center">
<button type="button"ng-click="addOptions()" class="btn options" formnovalidate>More Options</button>
</div>
<br>
<div class="text-center">
<button type="submit" class="btn button" validate>Submit</button>
</div>
</form>
</div>
<div ng-show="button" >
<br>
<div ng-repeat="poll in userVal2">
<div class="polldeco">
{{poll[0].title}}
<button class="btn buttondeco" ng-click="delete(poll)">Delete</button>
</div>
</div>
</div>
Some ideas:
$scope.userVal2 = Auth.getCurrentUser().polls is using the old version prior to the creation of a new poll? Maybe this could be changed to something like Auth.getCurrentUser().then(...). Either way, ensure that the call to getCurrentUser() is returning new data.
ng-view is cached. When a template is initially requested, it gets stored in the $templateCache. If this template is rendered on the backend for display in as a partial (eg: ng-view) and it is not static content, then you will have to invalidate the cache to update the view.
Consider having the backend return the new poll from $http.post('/api/users/update' ...) and adding it to the list used by ng-repeat. Something like:
$scope.process = function(name, values) {
$scope.polls.push({title:name, options:values});
...
$http.post('/api/users/update' + $scope.userVal._id, {polls: $scope.polls}).success(function(poll){
$scope.polls.push(poll);
});
};
...
<div ng-repeat="poll in polls">
<div class="polldeco">
{{poll[0].title}}
<button class="btn buttondeco" ng-click="delete(poll)">Delete</button>
</div>
</div>
I have a select dropdown for returnreasons that is populated from DB. If user is in specific role he can add new reasons. The problem is that my model in dropdown is not updating automatically after adding? The adding goes to DB though, but in the view dropdown is not populated again even if the model has changed.
<select class="form-control" ng-model="selectedReason">
<option ng-selected="{{reason.returnreasonId === selectedReason}}"
ng-repeat="reason in returnreasons"
value="{{reason.returnreasonId}}">
{{reason.returnText}}
</option>
</select>
<div class="form-group form-group-lg" ng-show="addReasonToggle">
<label class="col-md-2 control-label">New reason:</label>
<div class="col-md-8">
<input type="text" class="form-control" ng-model="returnReason.returnText" placeholder="New reason for return">
</div>
<div class="col-md-2">
<button class="btn btn-small btn-primary" ng-click="addNewReturnReason(returnReason)">Lisää</button>
</div>
</div>
In controller
$scope.addNewReturnReason = function(returnReason){
var savedReturnReason = [];
if (returnReason === undefined || returnReason === null) {
console.log("returnReason null");
} else {
// This is default value
returnReason.languageLanguageId = $scope.languages[0];
savedReturnReason = returnReasonSvc.save({}, returnReason);
savedReturnReason.$promise.then(function (result) {
$scope.returnReason = result;
$scope.returnreasons = returnReasonSvc.query();
$scope.addReasonToggle = false;
$scope.selectedReason=savedReturnReason;
});
};
}
Could be a problem of watch cycle is not running you can try this in your then function..
$scope.$apply();
to run manually .hope so it will work .
Hey so I have a form which has three fields name,email and phone.
<div ng-show="Nerd.adding">
<form class="col-sm-6" name="Nerd.nerdAddFrm" novalidate >
<div class="form-group">
<label for="inputName">Name</label>
<input type="text" class="form-control" id="inputName" placeholder="Name" ng-model="Nerd.nerd.name" required >
</div>
<div class="form-group">
<label for="inputEmail">Email</label>
<input type="email" class="form-control" id="inputEmail" placeholder="Email" ng-model="Nerd.nerd.email" required >
</div>
<div class="form-group">
<label for="inputPhone">Phone</label>
<input type="text" class="form-control" id="inputPhone" placeholder="Phone" ng-model="Nerd.nerd.phone" required >
</div>
<button ng-click="Nerd.saveNerd(Nerd.nerd)" type="submit" class="btn btn-primary">Submit</button>
<button ng-click="Nerd.load()" type="button" class="btn btn-default">Cancel</button>
</form>
</div>
As you can see the cancel button calls a Nerd.load() function in the controller. The controller basically resets the view and resets all the binded data to the model.
Nerd.load = function () {
Nerd.editing = false;
Nerd.adding = false;
Nerd.nerd = [];
nerdResource.query(
function (data) {
Nerd.nerds = data;
}
);
};
You can see that I am setting Nerd.nerd equal to an empty array. This should empty out the form fields data. It works fine for Name and Phone. But when I go back to the page it still shows what was last typed. There is no page reload as I am showing and hiding divs based on controller variables. EG <div ng-show="Nerd.adding">. Can anyone help me out with this?
I am on angularjs version 1.3.14. Any help on this would be great.
Thanks.
You need to attach these variables to your $scope like so:
$scope.Nerd.load = function () {
$scope.Nerd.editing = false;
$scope.Nerd.adding = false;
$scope.Nerd.nerd = [];
nerdResource.query(
function (data) {
$scope.Nerd.nerds = data;
}
);
};
Also, I think you should set $scope.Nerd to an empty object like:
$scope.Nerd = {};
instead of setting it to an empty array. You need to use $scope when interacting with the view. This code doesn't look the angular the way it is currently written.
If you can try according some way.
Nerd.load = function () {
Nerd.editing = false;
Nerd.adding = false;
Nerd.nerd = [];
nerdResource.query(
function (data) {
Nerd.nerds = data;
Nerd.nerd = []; // Put here and array make Empty
}
);
};