ng-messages dynamic form name [duplicate] - angularjs

From the Docs:
Embedding interpolation markup inside expressions
Note: AngularJS directive attributes take either expressions or interpolation markup with embedded expressions. It is considered bad practice to embed interpolation markup inside an expression:
— AngularJS Developer Guide - Interpolation
I am looking for a well written canonical answer to which I can point readers.

From the Docs:
Why mixing interpolation and expressions is bad practice:
It increases the complexity of the markup
There is no guarantee that it works for every directive, because interpolation itself is a directive. If another directive accesses attribute data before interpolation has run, it will get the raw interpolation markup and not data.
It impacts performance, as interpolation adds another watcher to the scope.
AngularJS Developer Guide - Interpolation

Directives which expect Boolean values won't work:
ERRONEOUS
<input type="checkbox" ng-hide ="{{x.thenumber === null}}" />
When the expression evaluates to the Boolean value false, interpolation will return the string "false". Strings that have length greater than zero are truthy. The ng-hide directive will always hide and never show the input element.
CORRECT
<input type="checkbox" ng-hide="x.thenumber === null" />

Related

When to use double braces {{}} in angularJS

Taken from the Angular documentation:
Angular Expressions
Angular expressions are JavaScript-like code snippets that are mainly
placed in interpolation bindings such as
<span title="{{ attrBinding }}">{{ textBinding }}</span>
but also used directly in directive
attributes such as ng-click="functionExpression()".
For example, these are valid expressions in Angular:
1+2 a+b user.name items[index]
However I'm a little confused as to when to use the double braces syntax {{}} and when not to. The documentation seems to suggest that you don't need them when using expressions within the directive attributes (see the ng-click example above).
Although the following code which works offers anecdotal evidence to the contrary:
<ul id="Menu">
<li ng-repeat="appModule in applicationModules"
id="{{appModule.Name}}"
ng-class="{ 'selected' : selectedAppModule == '{{appModule.Name}}' }"
ng-click="menuClicked(appModule.Name)">
{{appModule.Display}}
</li>
</ul>
Note how in the ng-class directive the double braces are used and inside the ng-click directive they are not.
How do you know when to use them and when not to?
It depends on the directive attribute in question and the type of binding it uses. Further more it depends on what you intend in the given situation.
From your example:
ng-repeat="appModule in applicationModules"
No need for the braces as this expression is evaluated by angular inside the ng-repeat directive.
id="{{appModule.Name}}"
Here we need braces as we want the id to be equal to the value of the expression.
ng-class="{ 'selected' : selectedAppModule == '{{appModule.Name}}' }"
I'm pretty sure this can be written as:
ng-class="{ 'selected' : selectedAppModule == appModule.Name }"
And you get the same behaviour.
ng-click="menuClicked(appModule.Name)"
In this example we need the ng-click to be bound to the method named menuClicked.
Generally we use {{}} when we want to evaluate the expression and when dealing with attributes we don't always need to use {{}} as they are in many cases evaluated behind the scenes.
Simple Tip A rule of thumb for when {{}} is needed is by thinking of it as a wrapper for a .ToString()-method. Does converting the expression to a string make sense, then so does using {{}}. (Any counter examples are very welcome)
Check the documentation. Avoid using using interpolation {{ }} when
the documentation says that the directive takes an expression, . In the case of ng-src, the documentaion explicitly says use {{ }}. If the attribute is not an AngularJS directive, use interpolation.
Erroneous
ng-class="{ 'selected' : selectedAppModule == '{{appModule.Name}}' }"
The above example is an example of mixing interpolation and Angular epressions.
Instead use:
ng-class="{ 'selected' : selectedAppModule == appModule.Name }"
From the Docs:
Why mixing interpolation and expressions is bad practice:
It increases the complexity of the markup
There is no guarantee that it works for every directive, because interpolation itself is a directive. If another directive accesses attribute data before interpolation has run, it will get the raw interpolation markup and not data.
It impacts performance, as interpolation adds another watcher to the scope.
Since this is not recommended usage, we do not test for this, and changes to AngularJS core may break your code.
— AngularJS Developer Guide - mixing interpolation and expressions
Update
Don't use interpolation with:
ng-selected, see AngularJS ng-selected Directive API Reference
ng-disabled, see AngularJS ng-disabled Directive API Reference
ng-required
ng-if
ng-show
ng-hide
ng-open
ng-value
ng-repeat
ng-options

How to interpolate expressions in ng-messages directive?

Let's say that I have a form name "signupForm". When I use the ng-disabled directive on a button (to disable the form in case its invalid), I use
ng-disabled="{{formName}}.$invalid"> (formName contains the value signupForm)
When I inspect the button in browser, the above directive evaluates to ng-disabled="signupForm.$invalid">. This is perfect. The problem is that when I try to use the same expression inside of the ng-messages directive, like: ng-messages ="{{formName}}.$error"> the expression is NOT interpolated. So if I use the directive on a div and inspect it in browser, I see it as:
<div ng-messages="{{formName}}.$error"></div> whereas I expect it to be shown as <div ng-messages="signupForm.$error"></div>. But this does not happen.
So what can be done to make the ng-messages directive interpolate the expression & show it correctly? I have tested this issue with AngularJS 1.4.7 & 1.5.0-rc.1 and the issue exists in both of them. Any help is appreciated. Thank you.
ng-messages=this[formName].$error
ng-messages doest not allow interpolation in attribute value.
but we can pass expression to be evaluated.
this in html represent current scope and it has all the information about form with validations too. you can log it and see yourself.
ng-messages="this[formName][fieldName].$error"
ng-messages="this[formName].$error"
will work, worked for me

when should I write code with `{{}}` and without `{{}}` in html of angular js project

May be This is a simple question but it is challenging for me.
In angularJS when i write {{}} in html code so i write code like this like
if i talk about dynamic id, we write like code this
<div ng-repeat = 'item in itmes track by $index'>
<div id = "div-{{$index}}">{{item.name}}</div>
</div>
If i use any model without {{}} i write this example
<input id = 'name' ng-model = "item.name"/>
whenever i am coding in angular js, i write code without {{}} then if it is not work then i try code with {{}} and vise versa. and randomly 1 will correct
Question is when i write code with {{}} and without {{}} in html code ?
After the OP explained what exactly was the problem.
So, the question here is very simple: when do we use {{}} and when we don't in the context of ng-model.
When you do a <input type=... ng-model="someModel>, what you're essentially telling Angular is: "Here is an input element; attach $scope's someModel variable to the value of this input element.
Now, you can use this in your JavaScript controller like so: $scope.someModel, but what about HTML? We have a templating language in Angular, and when you give it some variable (say someModel), it'll search its $scope for it, and then put in the value there. If it is unable to, it'll throw a nasty error.
In essence, {{}} GETS the value, without that, you generally set the variable to gold the value of something.
Very simply put, AngularJS thinks that the content within the brace is an expression, which must be resolved. Once it is, Angular puts the value of the resolved expression there. In the most basic of the terms, you just tell it: "Here is some expression; put the evaluated value instead."
In ES6, we call it template strings.
So, you'll use it for expressions which mutate after every iteration. Say, a loop or something. Places where you know what the answer is, or you have static content, you won't use it.
Say you have the following bit of code:
...
...
$scope.figureOne = 10;
in your controller.js and the following in its view file:
<div>My age is {{ figureOne }}</div>
Angular gets the value from the $scope, and puts it there; so, the rendered form will be: My age is 10. However, if you had the following
<div>My age is figureOne</div>
This time, Angular knows that there is nothing to evaluate or resolve, so, it'll just render it as it is: My age is figureOne.
I hope I made it clear! :)
Angular directives have different types of parameters. Some parameters (#) expect string values and some expect javascript expressions (=) (with variables bound to $scope).
There's no obvious way to know which parameter expects what type of value (aside from looking at documentation).
If a variable expects static string value and you have an angular expression
then you'll need to evaluate it by wrapping in {{}}
If there variable expects an expression and you have an expression
simply type that in.
It's the best to avoid using {{}} where possible, your dynamic ID will fail when Angular hasn't interpolated the expression yet, use ng-attr-id="div-{{$index}} for that. https://docs.angularjs.org/guide/directive#-ngattr-attribute-bindings
Another example, if you have a slow connection and Angular isn't loaded yet users will see the {{}}, you can avoid this by using ng-bind="".
See this thread for more info: AngularJS : Why ng-bind is better than {{}} in angular?
It is very simple.
{{something}} - used for one way binding(Static).
<input type="text" value="{{something}}">
Now if you change its value in HTML ,you can not get it by $scope.something in js.
but If you use ng-model="something",you can get its value in JS.
This happens because ng-model is two way binding.
<input type="text" ng-model="something">
Mostly We use ng-model for forms and {{}} to display static information like User details or else.

Difference between ng-bind and interpolation {{}} in Angular [duplicate]

This question already has answers here:
AngularJS : Why ng-bind is better than {{}} in angular?
(12 answers)
Closed 1 year ago.
Is there any difference between
{{ }} and ng-bind in angular.
I am quite new to Angular. I started with using {{ }} and then in the documentation i find ng-bind. I think they do the same work but then why an extra directive, if not then please tell the difference.
There is some hint in the official docs: https://docs.angularjs.org/api/ng/directive/ngBind
Typically, you don't use ngBind directly, but instead you use the
double curly markup like {{ expression }} which is similar but less
verbose.
It is preferable to use ngBind instead of {{ expression }} if a
template is momentarily displayed by the browser in its raw state
before Angular compiles it. Since ngBind is an element attribute, it
makes the bindings invisible to the user while the page is loading.
The most obvious difference between them is Flash of Unstyled content while using {{ ... }}.
However, there is a more subtle difference between the two if the object you pass to {{ obj }} and ng-bind="obj" is not a string.
From https://stackoverflow.com/a/19744728/987185 :
Depending on whether you use {{ ... }} or ng-bind syntax, the
.toJSON and the .toString function on your object will be called
to determine its representation.
In addition to the above mentioned answers,
Performance Issues with Interpolation:
As explained in this thread better,
ng-bind is a directive and will place a watcher on the passed variable. So the ng-bind will only apply when the passed value does actually change.
The brackets on the other hand will be dirty checked and refreshed in every $digest, even if it's not necessary.
{{ }} can flash when the page is loading, ng-bind hides the expression properly until it is displayed correctly.
In AngularJs ng-bind directive works as alternative to the interpolation directive {{ }}. By inserting an ng-bind attribute to HTML element we can insert AngularJS data into it.
Here is an example:
<div ng-controller="DemoController" >
<span ng-bind="demoData.doThis()"></span>
</div>
The Key Difference is ng-bind attribute wont show Html content on page loading, where as interpolation Directive show as flash of content without style while page loading.
Another difference is the way ng-bind and interpolation display the data.
ng-bind calls the toString() method, whereas interpolation uses a custom "stringify" function.
Example
<div ng-controller="showClockCtrl">
<p>The current time is {{currentDateTime}}.</p>
<p>The current time is <span ng-bind="currentDateTime"></span>.</p>
</div>
<div ng-controller="showClockCtrl">
<p>MyObject is {{myObject}}</p>
<p>MyObject is <span ng-bind="myObject"></span></p>
</div>
<script>
var showClockCtrl = function ($scope) {
$scope.currentDateTime = new Date();
$scope.myObject = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3'
}
};
</script>
Output
The current time is "2017-11-18T15:09:59.429Z".
The current time is Sat Nov 18 2017 10:09:59 GMT-0500 (EST).
MyObject is {"key1":"value1","key2":"value2","key3":"value3"}
MyObject is [object Object]
Sometimes when we load our application in the browser , we can notice flashing content for some milliseconds before {{ name }} is resolved and data is loaded.
This happens because the template is loaded before AngularJS had a chance to go in and compile the elements. To resolve this issue, you can use ng-cloak directive.
In the first approach(i.e. {{}}), AngularJS evaluates the expression then replaces it with some value which sometime be left with the flashing double curly brackets but ng-bind saves this time by informing AngularJS to put the contents of the expression within the element itself.
Note:
{{}} sometimes cause performance issue if we have thousand of bindings in our page.In these scenario's, we should go with ng-bind.
Interpolation is only used for a Read-only purpose and you cannot assign a value to inside the mustache bracket to a variable that has been declared inside the Typescript file.
The basic difference between them is that ng-bind should always be used inside the element <> but Interpolation directive can be used inside, outside and between the elements.
Not an answer, but ng-bind is easily exchangable by ng-bind-html, which puts actual html text inside the element instead of pure text.
Since I was wondering for (ok, just) minutes, I add it here as well. My problem was, text-DOM explorer shows the same output.

Angular interpolation expression not evaluated

I am having an issue with Angular interpolation.
I have a directive template that looks like this:
<div class="autocomplete {{attrs.class}}" id="{{attrs.id}}">
<input type="text" {{attrs.autofocus | toAutofocusText}} ng-model="searchParam" placeholder="{{attrs.placeholder}}"/>
...
</div>
The problem I have is that this expression is not evaluated:
{{attrs.autofocus | toAutofocusText}}
However, if I change this to something like this:
x="{{attrs.autofocus | toAutofocusText}}"
It does get evaluated.
Could someone explain me why this would be happening? I am guessing it is something fairly fundamental, but I can't find anything on Google.
So the answer is that attributes don't get interpolated on that level. Or to be more specific, at the time when your HTML is compiled, angular processes DomElements. A Dom element with an attribute that starts with {{ isn't a valid attribute, which is why the $compile don't know about it. However, it does now about such expressions within attribute values, or Dom element contents.
Remember that angular is (they say) what html would be if written for applications. The data binding syntax is evaluated as html. Saying:
x="{{attrs.autofocus | toAutofocusText}}"
is different because now you are talking about an attribute's property being evaluated not some unknown characters inside an html element.
Another thing I would recommend is you look into using ng-class for manipulating the class stuff:
http://docs.angularjs.org/api/ng/directive/ngClass

Resources