Not being able to iterate through inputs within scope - angularjs

I'm trying to iterate through an array created using angular, so I can add them up and then show them, but the problem is, I'm getting an error saying that property '1' of undefined even if I fill out the input field, why is this?
My code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<title>jQueryForm</title>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div id="form" ng-init="dataSet = [{},{},{},{},{}]">
<div ng-repeat="data in dataSet">
<input type="checkbox" ng-model="data.checked" />
<label>Data:</label>
<input type="number" ng-model="data.number" />
<br/>
</div>
<span>{{result}}</span>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
for (var i = 1; i < 5; i++) {
$scope.result += $scope.dataSet[i];
}
});
</script>
</div>
</div>
</span>
</body>
</html>

As ng-init is special kind of directive which evaluates expression provided to it in preLink function of directive.
PreLink function: - this function gets evaluates after scope has been
created for that element
By reading above line you will come to know that it has evaluated for loop before $scope.dataset getting available. Which is obiviously going to get fail.
I'd say don't use ng-init for such cases. Place that initialization data inside controller itself.
Code
//remove ng-init directive from UI
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
function init(){
for (var i = 1; i < 5; i++) {
if($scope.dataSet[i].checked)
$scope.result += $scope.dataSet[i].number;
}
}
//init
$scope.dataSet = [{},{},{},{},{}]
init();
});

You have to initialize dataSet differently this time around. Just add it to the controller's scope instead of using ng-init.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<title>jQueryForm</title>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div id="form">
<div ng-repeat="data in dataSet">
<input type="checkbox" ng-model="data.checked" />
<label>Data:</label>
<input type="number" ng-model="data.number" />
<br/>
</div>
<span>{{result}}</span>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.dataSet = [{},{},{},{},{}];
for (var i = 1; i < 5; i++) {
$scope.result += $scope.dataSet[i];
}
});
</script>
</div>
</div>
</span>
</body>
</html>
To make the code work, though, you'll have to change a few things. The loop in which you try adding the numbers will be called only once - at instantiation time of the controller. At that time, no number has been entered, yet. You could solve it with a button. (Also add up the numbers, not the objects in dataSet)
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<title>jQueryForm</title>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div id="form">
<div ng-repeat="data in dataSet">
<input type="checkbox" ng-model="data.checked" />
<label>Data:</label>
<input type="number" ng-model="data.number" />
<br/>
</div>
<button ng-click="calculate()">calculate</button>
<span>{{result}}</span>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.dataSet = [{},{},{},{},{}];
$scope.calculate = function() {
$scope.result = 0;
for (var i = 0; i < $scope.dataSet.length; i++) {
if(angular.isNumber($scope.dataSet[i].number) && $scope.dataSet[i].checked)
$scope.result += $scope.dataSet[i].number;
}
};
//Edit. Doesn't have the best performance, keep dataSet small
$scope.$watch('dataSet', function(newValue, oldValue) {
$scope.calculate();
}, true);
});
</script>
</div>
</div>
</span>
</body>
</html>
I fixed a few more things here and there. I assumed, you wanted to add only those numbers that were checked - also, the ng-models without a value were causing problems, that's why the check for being a number was introduced.
edit:
As you wanted to do it without the button: You can use a deep $scope.$watch.
https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch

Thanks to #Pankaj Parkar and #JanS, I finally made what I wanted to, everytime the input is changed I call the function calculate(); and everytime a checkbox is clicked on I call it as well.
Code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
<title>jQueryForm</title>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div id="form">
<div ng-repeat="data in dataSet">
<input ng-click="calculate()" type="checkbox" ng-model="data.checked" />
<label>Data:</label>
<input ng-change="calculate()" type="number" ng-model="data.number" />
<br/>
</div>
<span>{{result}}</span>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.dataSet = [{}, {}, {}, {}, {}];
$scope.calculate = function() {
$scope.result = 0;
for (var i = 0; i < $scope.dataSet.length; i++) {
if (angular.isNumber($scope.dataSet[i].number) && $scope.dataSet[i].checked)
$scope.result += $scope.dataSet[i].number;
}
}
});
</script>
</div>
</div>
</span>
</body>
</html>

Related

How to limit the number of button clicks in Angular?

I am trying to make the button non-functional after the number of clicks are equal to the value entered in the text boy.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
Student <input type="input" ng-model="number"> <br>
<p> {{number}} </p>
<button ng-click= "myFunction()">Click Me!</button>
<p>{{ count }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.count=0;
$scope.number;
$scope.myFunction = function() {
$scope.count++;
$scope.count <= $scope.number;
}
});
</script>
</body>
</html>
If you're looking for a Angular 2+ implementation, you could use two-way binding to ngModel directive. Try the following
Controller
export class AppComponent {
buttonCount = 0;
studentCount = 0;
onClick() {
this.buttonCount++;
}
}
Controller
Student <input [(ngModel)]="studentCount" (keyup)="buttonCount = 0" type="input"> <br>
Number input: {{ studentCount }}
<br><br>
<button [disabled]="buttonCount >= studentCount" (mouseup)="onClick()">Click me</button>
<br>
Button clicks: {{ buttonCount }}
The (keyup)="buttonCount = 0" event in the input tag resets the button click count everytime a value is entered in the input.
Working example: Stackblitz
If you're new to Angular, I'd recommend you to go through this tutorial. It introduces some of the basics.
I would do something like this:
Add a ng-disabled attribute to the button, this will disable the button when the expression is truthy.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
Student <input type="input" ng-model="number"> <br>
<p> {{number}} </p>
<button ng-disabled="count >= number" ng-click= "myFunction()">Click Me!</button>
<p>{{ count }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.count=0;
$scope.number;
$scope.myFunction = function() {
$scope.count++;
$scope.count <= $scope.number;
}
});
</script>
</body>
</html>
If you are starting out and can switch, I would recommend trying Angular 2+ instead of AngularJS. It's much more intuitive IMO.
You can use ng-disabled directive. You can disable the button after the number of clicks.

simple ng-click is not working in AngularJS. Is there anything basic that im missing here?

Here is my aspx:
<body ng-controller="myController">
<form id="form1" runat="server">
<div>
<input type="button" value="Press" ng-click="incrementCount()" ng-init="count=0"/>
<span>{{ count }}</span>
</div>
</form>
</body>
and following is JS:
angular.module('myModule', [])
.controller('myController', function ($scope, $http) {
$scope.incrementCount = function () {
$scope.count = $scope.count + 2;
};
});
Whats wrong with my Code??
When I click the 'Press' button, it does not works as it should.
angular.module('myModule', []) .controller('myController', function ($scope, $http) {
$scope.incrementCount = function () {
$scope.count = $scope.count + 2;
};
});
<!DOCTYPE html>
<html lang="en-US">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body ng-app="myModule" ng-controller="myController">
<form id="form1" runat="server">
<div>
<input type="button" value="Press" ng-click="incrementCount()" ng-init="count=0"/>
<span>{{ count }}</span>
</div>
</form>
</body>
</html>
Its working normally ! Click RUN.

angularjs fetch value from textbox after clicking a button only

This is my code
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('myController', function ($scope) {
$scope.getName = function () {
$scope.name = fname;
$scope.lastName = lastName;
};
})
</script>
</head>
<body ng-app="myApp" >
<div >
<input type="text" ng-model="name"/> <br>
<input type="text" ng-model="lastName" />
</div>
<div ng-controller="myController">
<input type="button" value="click" ng-click="getName()" />
<br>
Hello FirstName {{name}}<br>
Last Name {{lastName}}
</div>
</body>
</html>
values are coming while typing into textbox but i want values only after clicking the button.Please help me.
I tried in both ways simple as well as by using service or factory method but no success
You must separate the ng-models of the input texts and destination field. They are updating real-time because of having the same models.
I have created the correct version for you:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('myController', function ($scope) {
$scope.getName = function () {
$scope.nameToSet = $scope.name;
$scope.lastNameToSet = $scope.lastName;
};
})
</script>
</head>
<body ng-app="myApp" >
<div >
<input type="text" ng-model="name"/> <br>
<input type="text" ng-model="lastName" />
</div>
<div ng-controller="myController">
<input type="button" value="click" ng-click="getName()" />
<br>
Hello FirstName {{nameToSet}}<br>
Last Name {{lastNameToSet}}
</div>
</body>
</html>
UPDATE: Here is another version with using a factory:
var myApp = angular.module('myApp', []);
myApp.factory('container', function() {
var model = {
name: '',
lastName: ''
};
return {
model: model,
setName: function(nameToSet) {
model.name = nameToSet;
},
setLastName: function(lastNameToSet) {
model.lastName = lastNameToSet;
}
};
});
myApp.controller('myController', function ($scope, container) {
$scope.$watch('name', function(newvalue,oldvalue) {
container.setName(newvalue);
});
$scope.$watch('lastName', function(newvalue,oldvalue) {
container.setLastName(newvalue);
});
$scope.onNameType = function(value) {
container.setName(value);
};
$scope.onLastNameType = function(value) {
container.setLastName(value);
};
$scope.getName = function () {
debugger;
$scope.nameToSet = container.model.name;
$scope.lastNameToSet = container.model.lastName;
};
})
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
</head>
<body ng-app="myApp" >
<div >
<input type="text" ng-model="name" ng-change="onNameType(name)"/> <br>
<input type="text" ng-model="lastName" ng-change="onLastNameType(lastName)" />
</div>
<div ng-controller="myController">
<input type="button" value="click" ng-click="getName()" />
<br>
Hello FirstName {{nameToSet}}<br>
Last Name {{lastNameToSet}}
</div>
</body>
</html>

one controller two view

I have a view where the user gives an input and display it in another view.
view 1:
<ion-content ng-controller="controller">
<input type="text" ng-model="name">
<button ng-click="save()">Save</button>
Controller:
$scope.save = function () {
$scope.displayName = $scope.name;
$state.go('app.viewTwo');
}
View 2:
<ion-content ng-controller="controller">
{{displayName}}
</ion-content>
Its known, that whenever a view is loaded the controller is initialized fresh every time. So how to display the value from the first view, in another view.
You need to use a service or factory to use the variable across the controllers.
DEMO:
var app = angular.module("clientApp", [])
app.controller("TestCtrl",
function($scope,names) {
$scope.names =[];
$scope.save= function(){
names.add($scope.name);
}
$scope.getnames = function(){
$scope.names = names.get();
}
}
);
app.factory('names', function(){
var names = {};
names.list = [];
names.add = function(message){
names.list.push({message});
};
names.get = function(){
return names.list;
};
return names;
});
<!doctype html>
<html >
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="clientApp">
<div ng-controller="TestCtrl">
<input type="text" ng-model="name">
<button ng-click="save()" > save</button>
</div>
<div ng-init="getnames()" ng-controller="TestCtrl">
<div ng-repeat="name in names">
{{name}}
</div>
</div>
</body>
</html>
You can also use $rootScope , but it is not a recommended way.

Angular Js Basic Controller Return Error

Angular Controller return error when called through an app. But works when written directly.
My html code
<!DOCTYPE html>
<html ng-app>
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body ng-app="fbapp">
<div ng-controller="fbController" class="container">
<input type="text" name="name" ng-model="name"/>
<input type="button" value="Fetch" ng-click="fetchUser()" class="btn btn-primary"/>
</form>
</div>
</body>
</html>
My js code
var fbapp = angular.module('fbapp', []);
fbapp.controller('fbController', function($scope){
$scope.fetchUser = function() {
$scope.name = "Test";
}
}
Error I get
Error: [ng:areq] http://errors.angularjs.org/1.2.15/ng/areq?p0=fbController&p1=not%20a%20function%2C%20got%20undefined
at Error (native)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js:6:450
at wb (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js:18:360)
at Qa (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js:18:447)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js:65:470
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js:52:156
at r (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js:7:386)
at J (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js:52:18)
at h (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js:46:28)
at h (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js:46:45)
It work for me if I don't declare container in a an app. Like...
function fbController ($scope){
$scope.fetchUser = function() {
$scope.name = "Test";
}
}
I am having no clue whats wrong.
as Stewie said you need to add closing parenthesis ' )'.
Example:
var app=angular.module('App', []);
app.controller('fbController', function($scope){
$scope.fetchUser = function() {
$scope.name = "Test";
}
})
html:
<div ng-app="App" >
<div ng-controller="fbController">
<button ng-click="fetchUser()">click</button>
<p >{{name}}</p>
</div>
</div>
Live example: http://jsfiddle.net/choroshin/7Ws6w/1/

Resources