AngularJS: is 0 == 2? [duplicate] - angularjs

This question already has answers here:
How to parseInt in Angular.js
(7 answers)
Closed 6 years ago.
I am scratching my head here. I am using angularJS and trying to use the expression that contains call to parseInt.
{{0 == 2}}
...prints out false as expected.)
However, when I am trying:
{{parseInt(0) == parseInt(2)}}
... it prints out... true !
How can this be possible?

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.
Refer
In your html
Both parseInt(0) and parseInt(2) are undefined in your html.
So {{undefined==undefined}} is true.Beacause parseInt is a Javascript function.So you cant access the parseInt function in side {{}}. [Here parseInt is not a scope variable]
Solution
If you wish to do this,
define parseInt in your controller,
$scope.parseInt = parseInt;
Then you can use the parseInt method in your html

That's because parseInt is not defined in your scope.
http://jsfiddle.net/halirgb/Lvc0u55v/

You can't execute regular JS in an angular expression. Your expressions will be evaluated against the current scope. So, parseInt is undefined in the current scope.
If you set parseInt as a function reference, it will work.
$scope.parseInt = parseInt;

This is because the view is attached to the controller via scope.
So whatever we write in view either a variable or a function or anything it's rendered by appending $scope in front of it.
eg.
a is rendered as $scope.a in the view
So when we write parseInt, its rendered by $scope.parseInt which is not defined.
FIX- define $scope.parseInt = parseInt in the controller attached to the particular view

You have comparing both undefined values so result will be true.
You cannot call a javascript method(parseInt) via angular directives(ng-blur,ng-change,..) either you can achieve by making angular functions.
Solution 1:
{{0*1 == 2*1}}
Just do a trick to convert to Integer by multiply with 1 (0*1 = 0, 2*1 =1).
Solution 2:
{{parseInt(0) == parseInt(2)}}
Controller:
// To Convert specific format
$scope.parseInt = funtion(value){
return parseInt(value,10);
}
or
$scope.parseInt = parseInt;
reference here

Related

two way binding on primitive variables in angularjs directive

Trying to have 2 way binding on an AngularJS directive while using primitive objects is not working, for example:
<custom-directive ng-model="variable"></custom-directive>
how can this be achieved?
In order to have 2 way binding in javascript (not just angularjs), we have to pass an object (this is caused by javascript's evaluation strategy - can read more about it here https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing). basically what is happening is that when we pass a primitive variable, its been passed by value and re-created, instead of been passed by reference. only objects are passed by reference.
So this issue can be solved by passing the variable's parent object, for example:
<custom-directive ng-model-name="variable" ng-model-parent="parentObj"></custom-directive>
and then, modifying in object in the directive as following:
parentObj[variable] = "whatever";
this way, we will keep the connection between the variable to the parentObj.
another option would be passing the model with the parent obj, for example:
<custom-directive ng-model="parentObj.variable"></custom-directive>
the dot is an important part of this example. its actually a best practice by angular to always pass variables with the parentObj-dot-property.
for additional information, angularjs actually has a documentation about it https://github.com/angular/angular.js/wiki/Understanding-Scopes
I just realized that if your directive isn't inside an ng-if it will work with primitive bindings. Maybe the problem is that your bind is inside an ng-if. Try to use ng-show instead. Maybe it will work.
Passing the primitive this way:
<custom-directive ng-model="parentObj.variable"></custom-directive>

Angular ng-init assignment inside of a template

I need to initialize an object in my view and assign a reference to it.
Can I achieve this by using ng-init? Is it an assignment by value or reference?
<ANY ng-init="objA = objB"> ... </ANY>
Any help will be appreciated!
Move assignment to controller init() method.
ng-init is directive that have a very lot of side effects and hardly to trace it down. For example: when you use ng-init in directive template for creating/editing item and you assign some model value in it - you will achieve problem with editing that actually should use already existing value.
As well side effect of it is executing few times when you add ng-if.
Usage ng-init in templates are your own risk.
Right way: controller data should be defined at start of module - in any case any view started in order: $state -> resolve() -> controller -> template -> directive. It's not a good idea to fool yourself with not existing data until it will be created by magic.
In case of repeaters when you have for example empty {} and you need to display it like possibility to fill yet empty input, as I mentioned - you need to run function on init that can define empty or extend existing model by passing actual model.

How to differentiate when to use angular expression inside any of it's directive?

I am confused about when to use expressions and when not to use inside default AngularJS directives such as ng-src, ng-href and other.
According to my understanding when we use angular directive we have just use scope variable names to bind it's value. Following expression work properly.
<link ng-href="{{BASIC_PATH + '/relative-path-url/image.png'}}"/>
But consider an case of ng-model directive, following example is not valid way to bind variables.
<span ng-model="{{BASIC_PATH}}"></span>
Every time when I have to use angular expressions with directives, I used to write code in both format and then test.
So what is the basic fundamental way to use expressions with angular directives.
Using the {{ }} tells Angular to evaluate the variable and pass its value to the directive.
So if your controller contains the line:
$scope.myVar = "test";
Then this line:
<input ng-model="{{myVar}}">
Would basically be compiled to:
<input ng-model="'test'">
Therefore, the way to remember which convention you should use, is to ask yourself if the directive wants the variable itself, or the value of the variable.

Preventing second function from being called in same ng-click in angularjs

I have an ng-click with 2 functions in it.
Function1: A function in a directive that sets a scope variable to
true/false
Function2: A function in the controller
Right now in Function2 in the beginning I check the value of the scope variable from Function1 and if it's false I return false(i.e. stop it).
So my question is: can the Function2 not be called in case the first one returns false without writing anything in the Function2?
Thank you.
Try this:
ng-click="directiveFunction(); booleanVariable ? controllerFunction() : noop();"
From here: https://docs.angularjs.org/guide/expression
No Control Flow Statements
Apart from the ternary operator (a ? b : c), you cannot write a control flow statement in an
expression. The reason behind this is core to the Angular philosophy that application logic
should be in controllers, not the views. If you need a real conditional, loop, or to throw
from a view expression, delegate to a JavaScript method instead.

Can I do binding for element that is going to be created only at runtime in AngularJS?

What I'm really asking is this:
I have array of objects inside a service, that at first load it may be empty.
var arr = {};
In one view the array is being added with objects.
arr[obj.id] = something;
Can I do binding to {{arr[obj.id]}} in html or code?
Yes it is allowed. Expression evaluation is forgiving to undefined and null in Angular JS.
Refer this link from angular https://docs.angularjs.org/guide/expression

Resources