How to parseInt in Angular.js - angularjs

Probably, it is the simplest thing but I couldn't parse a string to Int in angular..
What I am trying to do:
<input type="text" ng-model="num1">
<input type="text" ng-model="num2">
Total: {{num1 + num2}}
How can I sum these num1 and num2 values?
Thnx!

You cannot (at least at the moment) use parseInt inside angular expressions, as they're not evaluated directly. Quoting the doc:
Angular does not use JavaScript's eval() to evaluate expressions.
Instead Angular's $parse service processes these expressions.
Angular expressions do not have access to global variables like
window, document or location. This restriction is intentional. It
prevents accidental access to the global state – a common source of
subtle bugs.
So you can define a total() method in your controller, then use it in the expression:
// ... somewhere in controller
$scope.total = function() {
return parseInt($scope.num1) + parseInt($scope.num2)
}
// ... in HTML
Total: {{ total() }}
Still, that seems to be rather bulky for a such a simple operation as adding the numbers. The alternative is converting the results with -0 op:
Total: {{num1-0 + (num2-0)|number}}
... but that'll obviously won't parseInt values, only cast them to Numbers (|number filter prevents showing null if this cast results in NaN). So choose the approach that suits your particular case.

Option 1 (via controller):
angular.controller('numCtrl', function($scope, $window) {
$scope.num = parseInt(num , 10);
}
Option 2 (via custom filter):
app.filter('num', function() {
return function(input) {
return parseInt(input, 10);
}
});
{{(num1 | num) + (num2 | num)}}
Option 3 (via expression):
Declare this first in your controller:
$scope.parseInt = parseInt;
Then:
{{parseInt(num1)+parseInt(num2)}}
Option 4 (from raina77ow)
{{(num1-0) + (num2-0)}}

<input type="number" string-to-number ng-model="num1">
<input type="number" string-to-number ng-model="num2">
Total: {{num1 + num2}}
and in js :
parseInt($scope.num1) + parseInt($scope.num2)

Perform the operation inside the scope itself.
<script>
angular.controller('MyCtrl', function($scope, $window) {
$scope.num1= 0;
$scope.num2= 1;
$scope.total = $scope.num1 + $scope.num2;
});
</script>
<input type="text" ng-model="num1">
<input type="text" ng-model="num2">
Total: {{total}}

var app = angular.module('myApp', [])
app.controller('MainCtrl', ['$scope', function($scope){
$scope.num1 = 1;
$scope.num2 = 1;
$scope.total = parseInt($scope.num1 + $scope.num2);
}]);
Demo: parseInt with AngularJS

This are to way to bind add too numbers
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.total = function() {
return parseInt($scope.num1) + parseInt($scope.num2)
}
})
</script>
<body ng-app='myApp' ng-controller='myCtrl'>
<input type="number" ng-model="num1">
<input type="number" ng-model="num2">
Total:{{num1+num2}}
Total: {{total() }}
</body>
</html>

Inside template this working finely.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="">
<input ng-model="name" value="0">
<p>My first expression: {{ (name-0) + 5 }}</p>
</div>
</body>
</html>

Related

AngularJS $watch not working properly

Recently I am learning Angularjs, my code seems not work as expected:
this is my div:
<div ng-app="myApp">
<div ng-controller="myController">
<input type="text" ng-model="data.name" value=""/>
{{data.count}}
</div>
</div>
my controller is:
<script>
var app = angular.module('myApp',[]);
app.controller('myController', function($scope) {
$scope.data = {
name:"tom",
count = 0
}
$scope.$watch('data', function(oldValue,newValue) {
++$scope.data.count;
},true);
})
</script>
what I expect is when I type something in the <input> box, the {{data.count}} will increase by 1 each time. However the code is initially 11 and each time I make changes in the input field, the count is increased by 11, can someone help me find where have I done wrong? Thanks a lot in advance.
Why this happen?
Watcher calls multiple times because you created watcher for full object data. Flag true will create sub-watcher for every value in object.
Its a proper behavior. I believe you want something like:
$scope.$watch('data', function(oldValue,newValue) {
if(oldValue.name != newValue.name){
++$scope.data.count;
}
},true);
Demo Fiddle
The second solution is to watch on name only:
$scope.$watch(function(){
return $scope.data.name
}, function(oldValue,newValue) {
++$scope.data.count;
});
Here is a another way to do it. Use the ng-keydown directive and update the count only when a key is pressed inside the input element.
var app = angular.module('myApp', []);
app.controller('MyController', function MyController($scope) {
$scope.data = {
name: "tom",
count: 0
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller='MyController' ng-app='myApp'>
<input type="text" ng-model="data.name" value="" ng-keydown="data.count = data.count+1" /> {{data.count}}
</div>

What's the error in this simple AngularJS calculator?

AngularJS newbie here. I'm trying to make a very simple calculator that adds two values in Angular 1.5. The value of calc.result doesn't update.
index.html
<body ng-app="Calculator">
<div class="container" ng-controller="calcCtrl as calc">
<input type="number" ng-model="calc.input1">
<span>+</span>
<input type="number" ng-model="calc.input2">
<span>=</span>
<input type="number" ng-model="calc.result">
</div>
<script src="js/angular.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers/calc.js"></script>
</body>
js/app.js
(function() {
angular.module('Calculator', []);
})();
js/controllers/calc.js
(function() {
angular
.module('Calculator')
.controller('calcCtrl', CalculatorControl);
function CalculatorControl()
{
this.input1 = 0;
this.input2 = 0;
this.result = this.input1 + this.input2;
}
})();
Simply change one row:
<span>=</span>
<input type="number" ng-value="calc.input1*1 + calc.input2*1">
You need to define a computed property to access a value that is dependent on other properties on the controller / scope.
To achieve it, javascript gives you the ability to have a getter on object, that you could use to compute the value, but still can access it as a property, in your case its result.
You could read more about Object.defineProperty on MDN.
Here is what you could do.
(function() {
angular.module('Calculator', []);
})();
(function() {
angular
.module('Calculator')
.controller('calcCtrl', CalculatorControl);
function CalculatorControl() {
this.input1 = 0;
this.input2 = 0;
Object.defineProperty(this, 'result', {
get: function() {
return this.input1 + this.input2;
}
});
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div ng-app="Calculator">
<div class="container" ng-controller="calcCtrl as calc">
<input type="number" ng-model="calc.input1">
<span>+</span>
<input type="number" ng-model="calc.input2">
<span>=</span>
<input type="number" ng-model="calc.result" ng-disabled="true" />
</div>
</div>
Make result as a function which will be calculation of input1 & input2. Also it doesn't make sense to edit result part by user, so instead of result as input field make it display only field.
Markup
<div class="container" ng-controller="calcCtrl as calc">
<input type="number" ng-model="calc.input1">
<span>+</span>
<input type="number" ng-model="calc.input2">
<span>=</span>
<span ng-bind="calc.result()"></span>
</div>
Controller
function CalculatorControl() {
var self = this;
self.input1 = 0;
self.input2 = 0;
self.result = function(){
var input1 = !isNaN(self.input1) ? self.input1: 0,
input2 = !isNaN(self.input2) ? self.input2: 0;
return input1 + input2;
}
}
Plunkr
First of all you are not calling the add function on a click event.
Then you are initializing the values of every function call.
You will need to do the addition in a separate method.

AngularJs can't run a method

I am a beginner angularjs user, but i have to learn it for my new job and I thought I could practice a bit. So I did a simple string reverse method and I thought I could make a simple calculator (exactly, only sum). Here is my code. I made 2 modules, 2 controllers and the first one is working fine, but the calculator isn't. However I made a simple site, where only the calc code is, and it works fine and I don't understand why it works, but doesn't work if 2 modules are on the same site.(Yeah, i'm a very beginner). Thank you for your help.
<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"> </script>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div ng-app="MyApp" ng-controller="myController">
<center>
<input type="text" ng-model="myString" placeholder="Enter text"/>
<p>Input: {{myString }}</p>
<p>Filtered input: {{getReverse()}}</p>
</center>
</div>
<br><br>
<center>
<div ng-app="MyCalc" ng-controller="myCalculate">
<input type="text" ng-model="firstNumber"><br>
<input type="text" ng-model="secondNumber"><br>
<p> Result: {{getResult()}}</p>
</div>
</center>
<script>
var reverse = angular.module("MyApp", []);
var calc = angular.module("MyCalc",[]);
reverse.controller('myController',function($scope){
$scope.myString = "";
$scope.getReverse = function(){
return $scope.myString.split("").reverse().join("");
}
});
calc.controller('myCalculate',function($scope){
$scope.firstNumber = 0;
$scope.secondNumber = 0;
$scope.getResult = function(){
return Number($scope.firstNumber)+Number($scope.secondNumber);
}
});
</script>
ng-app directive can be used just one time in page.
only one AngularJS application can be auto-bootstrapped per HTML document. The first ngApp found in the document will be used to define the root element to auto-bootstrap as an application. To run multiple applications in an HTML document you must manually bootstrap them using angular.bootstrap instead. (https://docs.angularjs.org/api/ng/directive/ngApp)
But you can bootstrap manually your app. Affect id on div that contains an angular app and add this to your script (https://plnkr.co/edit/ZTW7mXx3iXm803xdYod1?p=preview):
angular.bootstrap(document.getElementById('reverse'), ['MyApp']);
angular.bootstrap(document.getElementById('calc'), ['MyCalc']);
But I agree with Vikash, create more modules and less app :)
Normally, you should not use 2 angular app in a web page.
If you need to use different module, just make one depend on another.
Let's say your main module is MyApp and you need MyCalc's function, you do it like this (JsFiddle):
var calc = angular.module("MyCalc",[]);
calc.controller('myCalculate',function($scope){
$scope.firstNumber = 0;
$scope.secondNumber = 0;
$scope.getResult = function(){
return Number($scope.firstNumber)+Number($scope.secondNumber);
}
});
// Make MyApp module depend on MyCalc
var reverse = angular.module("MyApp", ["MyCalc"]);
reverse.controller('myController',function($scope){
$scope.myString = "";
$scope.getReverse = function(){
return $scope.myString.split("").reverse().join("");
}
});
And then in the HTML:
<body ng-app="MyApp">
<div ng-controller="myController">
<center>
<input type="text" ng-model="myString" placeholder="Enter text"/>
<p>Input: {{myString }}</p>
<p>Filtered input: {{getReverse()}}</p>
</center>
</div>
<br><br>
<center>
<div ng-controller="myCalculate">
<input type="text" ng-model="firstNumber"><br>
<input type="text" ng-model="secondNumber"><br>
<p> Result: {{getResult()}}</p>
</div>
</center>
</body>
P/s: If you really need to bootstrap 2 angular app in the same web page, you need to bootstrap it manually (JsFiddle):
angular.bootstrap(document.getElementById('calc'), ['MyCalc']);
calc is the id of the element you need to bootstrap the second app on
<div id="calc" ng-controller="myCalculate">
use ng-module instead of ng-app because ng-app can be used with one module in one page.
<div ng-module="MyModuleA">
<h1>Module A</h1>
<div ng-controller="MyControllerA">
{{name}}
</div>
<div ng-module="MyModuleB">
<h1>Just Module B</h1>
<div ng-controller="MyControllerB">
{{name}}
</div>
var moduleA = angular.module("MyModuleA", []);
moduleA.controller("MyControllerA", function($scope) {
$scope.name = "Bob A";
});
var moduleB = angular.module("MyModuleB", []);
moduleB.controller("MyControllerB", function($scope) {
$scope.name = "Steve B";
});
Use angular ng-modules to achieve this
here is the working [link] [1]
[1] http://jsfiddle.net/j5jzsppv/111/
<div ng-modules="MyModuleA, MyModuleB">
<div ng-controller="myController">
<input type="text" ng-model="myString" placeholder="Enter text"/>
{{myString}}
<p>Filtered input: {{getReverse()}}</p>
</div>
<div ng-controller="myCalculate">
<input type="text" ng-model="firstNumber"><br>
<input type="text" ng-model="secondNumber"><br>
<p> Result: {{getResult()}}</p>
</div>
var reverse = angular.module("MyModuleA", []);
var calc = angular.module("MyModuleB", []);
reverse.controller('myController', function ($scope) {
$scope.myString = "";
$scope.getReverse = function () {
return $scope.myString.split("")
.reverse()
.join("");
}
});
calc.controller('myCalculate', function ($scope) {
$scope.firstNumber = 0;
$scope.secondNumber = 0;
$scope.getResult = function () {
return Number($scope.firstNumber) + Number($scope.secondNumber);
}
});

angularjs manual bootstrapping does not update property value when input changes through method call

The problem, I have is AngularJS application is not updating the result when input changes in the input HTML field. If I turn this to auto bootstrapping it does work as expected. I do not know what am i doing wrong?
This is JS file.
angular.module('doublevalue', [])
.controller('DoubleController', ['$scope', function($scope){
$scope.value = 0;
$scope.double = function(value) { $scope.value = value * 2; }
}]);
angular.element(document).ready(function() {
var div3 = document.getElementById('App3');
angular.bootstrap(div3, ['doublevalue']);
});
JSFIDDLE version:
https://jsfiddle.net/as0nyre3/48/
HTML file:
<div id ='App3' ng-controller='DoubleController'>
Two controller equals
<input ng-model='num' ng-change='double(num)'>
<span> {{ value }}</span> </div>
Auto bootstrapping one link:
https://jsfiddle.net/as0nyre3/40/
Please help me!
This is working, with a problem like that you should always check your selectors
<div id="App3" ng-controller="myCtrl">
<input type='text' ng-model='name' ng-change='change()'>
<br/> <span>changed {{counter}} times </span>
</div>
<script>
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById('App3'), ['myApp']);
})
</script>

Angular - default value for model

Say I have some html as follows:
<html>
<head> angular etc. </head>
<body ng-app>
<div ng-controller="MyCtrl">
<input ng-model="weight" type="number" min="{{minWeight}}" max="{{maxWeight}}">
<p>{{weight}}</p>
</div>
</body>
</html>
and the following controller:
function MyCtrl($scope){
$scope.weight = 200;
$scope.minWeight = 100.0;
$scope.maxWeight = 300.0;
}
The "min" and "max" will show the user their input is bad, and if I hard code them to say, 100 and 300, it will make sure the value is never bound to the model at all (why isn't the behavior the same??). What I'd like to do is only actually change the "weight" if the value meets the input requirements. Any thoughts?
I don't fully understand what are you trying to do.
HTML:
<html>
<head> angular etc. </head>
<body ng-app="MyApp">
<div ng-controller="MyCtrl">
<input ng-model="weight" type="number" min="{{minWeight}}" max="{{maxWeight}}">
<p>{{weight}}</p>
</div>
</body>
</html>
Angular: [Edit]
var app = angular.module('myApp', []);
app.controller('MyCtrl', ['$scope', function MyCtrl($scope){
$scope.weight = 200;
$scope.minWeight = 100.0;
$scope.maxWeight = 300.0;
$scope.$watch('weight', function (newValue, oldValue) {
if(typeof newValue === 'number') {
if(newValue > $scope.maxWeight || newValue < $scope.minWeight) {
$scope.weight = oldValue;
}
}
});
}]);
But here is an example I made in jsFiddle. I hope this was a solution you were looking for.
[Edit]
http://jsfiddle.net/migontech/jfDd2/1/
[Edit 2]
I have made a directive that does delayed validation of your input field.
And if it is incorrect then it sets it back to last correct value.
This is totally basic. You can extend it to say if it is less then allowed use Min value, if it is more then allowed use Max value it is all up to you. You can change directive as you like.
http://jsfiddle.net/migontech/jfDd2/2/
If you have any questions let me know.

Resources