How to get element in ng-repeat by index? - angularjs

I have ng-repeat for <li> element:
<li ng-repeat="item in filtered =(categorySelect | filter:searchinput)" ng-class="categorySelect[$index]checked"
I tried to get attribute checked from object categorySelect like as:
categorySelect[$index]checked
But it does not work.

Because your JS syntax is invalid. Try one of these:
categorySelect[$index].checked
or
categorySelect[$index]['checked']
or preferably avoid $index altogether:
item.checked
Also you're using ng-class incorrectly, it works like this:
ng-class="{myClass: item.checked}"
This will add "myClass" if the checked property evaluates to true, and remove the class if it does not.
Also note that using "dot notation" with reserved keywords like "checked" can break older browsers, like IE9. If that occurs, and supporting IE is necessary, then try to use the array syntax I gave in the second example or use a different property name than "checked".

Related

Angularjs ng-class not updating when using object annotation style

I just noticed that something doesn't work in Angular (or it doesn't as I expected it to work) when using object in ng-class.
What do I expect?
When changing the name of a property in the object, the class should update accordingly.
What did I try?
I found that when I use object style annotation like
ng-class="{obj.prop: testExpression}" and the obj.prop changes (the expression keeping returning TRUE) the value inside ng-class changes but that in the class attribute doesn't.
the difference is between this [NOT WORKING]:
<tr ng-repeat="user in users" ng-class="{ {{user.genre}}: true}">
and this [WORKING]:
<tr ng-repeat="user in users" ng-class="user.genre">
See a plunkr here:
http://plnkr.co/edit/149ba2WQ5RK5XqLmWQWK?p=preview
The thing is I need to use object annotation in order to disable the class.
Is there something I am doing wrong or I just misunderstood Angular?
Or a third solution?
In short, { {{user.genre}}: true} is not a correct angularjs expression
For your solution, try ng-class="getClass(user.genre)"
and do whatever you want in getClass function
example
You are trying to evaluate an object here, hence for each key-value pair of object with a real (truthy) value the corresponding key is used as a class name. If you have single parameter you have to use like:
<tr ng-repeat="user in users" ng-class="user.genre: true">
In case of multiple parameter you have to use like:
<p ng-class="{strike: deleted, bold: important, red: error}">

AngularJS Expression

I have a quick question on AngularJS:
I have one property from JSON as
"icon-class": "home"
Now I need to do this in my html page:
<span class="{{sub.icon-class}}"></span>
the sub is some other object here.
But inspecting the DOM, the value of the above expression is always zero (0). I guess the dash(-) is acting like a subtraction here.
How to do it I could not make it resolve.
Please help.
In this case, you can use bracket notation to retrieve the value when the key has non-standard characters:
<span class="{{sub['icon-class']}}"></span>
Read more about accessing properties at MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors
You could do this:
<span class="{{sub['icon-class']}}"></span>
But in general I'd avoid hyphens in variable names

Generate dynamic expressions in ng-repeat

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.

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)">

AngularJS not able to include markup in IDs?

I have an array of 3 items and want them to be "ng-repeated"
<li ng-repeat="item in obj.items id="testobj{{testobj.number}}">
</li>
When I look at the page, it appears that the id of the "li" is just "testobj" for all 3 items and not testobj1 testobj2 testobj3 like I was expecting. What is the issue?
Your ng-repeat attribute is missing a final ".
The {{ }} binding is probably coming back with no data and so being treated as if it was an empty string. I see no reference to testobj (the scope variable) anywhere outside of your binding. Is this defined, or should your id read id="testobj{{item.number}}" or something similar?

Resources