Generate dynamic expressions in ng-repeat - angularjs

I have a ngRepeat element that has a delete button that triggers a confirmation message. I'm trying to make the confirmation message show with a dynamic expression like so:
<div ng-repeat="item in items">
<a ng-click="delete(item_id)"></a>
<span ng-show="{{item._id}}_delete">Are you sure you want to delete your review? </span>
</div>
I'm not sure if this is the right way to create dynamic expressions, but this is the only way I can get the expression to at least generate in html.
But I am getting this error for all the repeated items (with different item ids in each error):
Error: [$parse:syntax] Syntax Error: Token 'cb0a2a73ede6e3a9d7a58_delete' is an unexpected token at column 4 of the expression [543cb0a2a73ede6e3a9d7a58_delete] starting at [cb0a2a73ede6e3a9d7a58_delete].
^ the outputted item._id for that item is 543cb0a2a73ede6e3a9d7a58 for example.

Angular is expecting an expression there that returns true or false for ng-show. So just rendering a String won't really help. You could either define a controller function that resolves to true or false or just write the expression inline, like ng-show="item.id === 2".
But it seems that you want a confirmation dialog before deleting, in that case you should write a custom directive that intercepts the click action before executing it (unfortunately there is no such thing as ng-confirm in Angular built-in).
Here is an example of such a directive: https://gist.github.com/asafge/7430497

If you simply want to toggle a message to the user, you could simply make your span dependant on a scope variable that gets toggled, like so:
<a ng-click="delete(item_id); showDelete=!showDelete">item</a>
<span ng-show="showDelete">Are you sure you want to delete your review? </span>
JSFiddle here.
However, you probably want to wrap it all up into a directive like #frank blizzard mentioned.

try this one :)
AH, if item._id starts with a number it will get a error
Variable names must begin with a letter
link
so ng-show bound to a variable in the scope and it is dynamically creating. a_delete,b_delete will work fine but if it generate like 1_delete,2_delete it will result a error because those are starts with a number.
In your case item._id starts with number like 543cb0a2a73ede6e3a9d7a58 as you mentioned in you question. so ng-show ends with something like ng-show="543cb0a2a73ede6e3a9d7a58_delete". That should get a error because of violation of naming-conventions.

Related

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.

What's the difference between `ng-show` and `ng-hide`?

These attributes are both given either a true or false value, so what difference is there between them? It would make sense if there weren't values for them.
Am I missing something?
With ng-show the element is shown if the expression is true, it will hide if it is false
On the other hand with ng-hide the element is hidden if the expression is true and it will be shown if it is false.
Just two sides of the same coin.
On a project I was working on before, I found having the option of both ng-show and ng-hide useful. The reason being is because I had a link in my navbar that was only supposed to show if the user was on a specific view. Here is that scenario:
<li ng-hide="isActive('/about') || isActive('/contact')" ng-class="{ 'vert-nav-active': isActive('/investigator')}" class="top-buffer">
Investigator Portal
</li>
Now, you might say, well you could just make the isActive('/about') || isActive('/contact') return the opposite Boolean and change the ng-hide to ng-show and every thing will stay the same but as you can see I'm also using this function to determine which link I'm on. If I reverse this logic, it will look like I'm on every link except the actual link I'm on. Granted I could write another function for the ng-show but I like reusing code that's already there.
Also worth mentioning is ng-if which takes a boolean expression just like ng-show and ng-hide but rather than just showing/hiding the elements depending on the expression, it completely removed the element from the DOM if the expression is false and put the element back in the DOM if the expression becomes true
i have a good scenario, let say you want to show one attribute or another depending on a validation, but not both, so using both ng-show and ng-hide like this:
<div ng-show="validation"></div>
<div ng-hide="validation"></div>
if the validation is true it would show the first div, but if it is false it would show the second div...
this can be done in many more ways but is a cleaver solution for a tricky problem :D
ng-show will only display the element IF the expression is true...
<span ng-show="true">Will Show </span>
<span ng-show="false">Will not Show </span>
ng-hide will not display the element IF the expression is true, but will display if the expression is false.
<span ng-hide="true">Will not display</span>
<span ng-hide="false">Will display</span>

AngularJS: What is the best way to pass a binded scope value through ng-click?

I have the follow code:
<li class='' ng-click="changeStatus('hello', '{{result.name}}')">
Where 'hello' is my first parameter for changeStatus and I want to pass of binded result.name's value as the second parameter. Does anyone know how to accomplish this?
I tried {{result.name}}, '{{results.name}}' but neither seems to work.
There is probably something simple that am I missing?
I took a look at:
Can you pass parameters to an AngularJS controller on creation?
but both the parameters in ng-init were string literals.
You don't have to pass it.
You could just access it in your controller using :
$scope.result.name
If results is an array and you want to pass an individual result to a controller click function you need not decorate it with curly braces. The li will look like this:
<li ng-repeat="result in results" ng-click="changeStatus('hello', result.name)">{{result.name}}</li>
Working Fiddle
Angular treats the content of ng-click as an expression. This means that you write the content as though it is plain javascript (in most cases). For your example, this means leaving out the curly braces (since you are already writing 'javascript').
<li class='' ng-click="changeStatus('hello', result.name)">

Don't evaluate variable in view

I have a site built with AngularJS. I need to put a text somewhere on the page that looks something like this: Use {{name}} to display the username.
But AngularJS automatically tries to evaluate {{name}}. But in this case I don't want it to be evaluated. I just simply want to show that as a text.
I already tried to use the unicode characters: {{name}}. But it still evaluates that...
Is there a way to do this?
Use the ngNonBindable directive
<span ng-non-bindable>Use {{name}} to display the username.</span>

elasticui - Triggering sort with ng-click only firing on first click

I'm trying to make the sort functionality work by creating two buttons: relevance and date.
I've set it up the following way:
<div ng-init="sort=false">
<a ng-click="sort=true">Date</a>
<a ng-click="sort=false">Relevance</a>
then on the container with the results:
<div eui-sort="ejs.Sort('post_date').order('desc')" eui-enabled="sort" >
The value set with ng-init properly affects the initial sort order and when I click date the list sorts as intended, but when I click relevance the list does not re-sort back as if eui-enabled was set to false.
I'm guessing underformed knowledge of Angular is causing me to oversimplify this. Any advice?
I suspect you're running into the AngularJS dot-problem, i.e.: the sort. A way to circumvent this is modifying sorting.sort within the eui-sort scope:
<div eui-sort="ejs.Sort('post_date').order('desc')" eui-enabled="true">
<a ng-click="sorting.enabled=true">Date</a>
<a ng-click="sorting.enabled=false">Relevance</a>
</div>
In this example, eui-enabled is only used for initialization since the value (true) doesn't change. Note that to reference the "sorting: object you must be inside the scope of the eui-sort (i.e.: inside the div)

Resources