How to use the ng-repeat $index variable in an AngularJs expression? - javascript

I'm generating a lot of HTML with ng-repeat. I rely on the $index variable in order to index data in my controller.
I do alot of stuff like
ng-submit="validateExistingGuest($index)"
In this case, an undetermined number of HTML forms is generated, hence the index.
Problem is, i sometimes need to use this variable inside a different kind of expression. That would look something like that:
ng-if= "user{{$index}}.valid"
Of course, that doesn't work. I tried ways of constructing that expression, with no success.
How would one go about doing this?

You need something like
ng-if="user[$index].valid

<div ng-repeat="value in user track by $index"> ...
//now you can use the {{$index}}
<div ng-if="user[$index].valid">Show only if valid!</div>
</div>

Why don't you use the object instead the $index?, try
<div ng-repeat="car in cars" >
<p {{car}}></p>
<button ng-click="buy(car)" > buy </button>
</div>

Related

Angularjs ng-repeat index not working

I want to use ng-repeat more or less as follows:
<div ng-repeat="One_Entry in Entries_List track by One_Entry.Entry_ID"
onClick="DoSomething(One_Entry.Entry_ID)">
<!---
present various fields within "One_Entry"
-->
</div>
Entries_List is a JSON array of objects, being Entry_ID one of the elements within the object.
DoSomething is a function within the related controller that is supposed to perform a specific activity on the structure whose ID is the passed Entry_ID.
I tried using $index as well as $parent.$index but I'm getting an error stating that these variable do not exist.
Could anyone tell me how I can achieve the above functionality?
Thanks.
The object One_Entry is scoped. Therefore onclick won't work. Use ng-click instead which is the Angular version for onclick:
<div ng-repeat="One_Entry in Entries_List track by One_Entry.Entry_ID"
ng-click="DoSomething(One_Entry.Entry_ID)">
<!---
present various fields within "One_Entry"
-->
</div>
It's not OnClick it's ng-click
Change
From :
<div ng-repeat="One_Entry in Entries_List track by One_Entry.Entry_ID"
onClick="DoSomething(One_Entry.Entry_ID)">
To:
<div ng-repeat="One_Entry in Entries_List track by One_Entry.Entry_ID"
ng-click="DoSomething(One_Entry.Entry_ID)">

Store value in a directive for later use

I would like to save an object in a ngRepeat so that I can use that object in its children, like shown in this code:
<div ng-repeat="bar in foo.bar>
<div ng-repeat="qux in baz.qux" myvalue="{'item1':foo.var1, 'item2':qux.var2}">
<div ng-click="myFirstFunction(myvalue)"></div>
<div ng-click="mySecondFunction(myvalue)"></div>
</div
</div
The object I want to generate and then use is rather large and I'd rather not define it repeatedly for each ngClick directive.
I considered saving it into a scope variable but the object will change for each iteration of the ngRepeat.
Is there a directive or an other way that I can use to store this value for later use?
To avoid the repetition of what is probably a long variable definition, you can use the ngInit directive, whose content will be executed each time a corresponding element is created.
<div ng-repeat="bar in foo.bar>
<div
ng-repeat="qux in baz.qux"
ng-init="myValue = {'item1':foo.var1, 'item2':qux.var2 }"
>
<div ng-click="myFirstFunction(myValue)"></div>
<div ng-click="mySecondFunction(myValue)"></div>
</div>
</div>
However, a complex code in a template is rarely a good idea. Contemplate moving your logic inside a controller, as advised by the documentation:
The only appropriate use of ngInit is for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
You can just do the naive thing here and it'll work:
<div ng-repeat="bar in foo.bar>
<div ng-repeat="qux in baz.qux">
<div ng-click="myFirstFunction(foo, quz)"></div>
<div ng-click="mySecondFunction(foo, quz)"></div>
</div>
</div>
Angular will know the scope of the repeat when you click.
You could store it in local storage using ng-storage.
https://github.com/gsklee/ngStorage
This would allow you to store it, then use it anywhere in the application.
cookies, you also have ng-cookies
https://docs.angularjs.org/api/ngCookies
try this out! or cookieStorage

Using ng-repeat on multiple arrays

I'm making a weather application but I'm stuck on what should be a simple task but I can't wrap my head around how this works since I'm new to Angular. Basically what I need is to iterate over two arrays at once and set some values from this array.
In theory this is what I wanna accomplish:
<div ng-repeat="city in cities" ng-repeat="temp in temperatures" id={{city.id}}>
<span>{{temp}}</span>
</div>
But obviously you can't put multiple repeaters like this. If I put an ng-repeat on the span I get 12 spans but I only need 1 and I need this 1 to contain the current value of the iteration in the temperatures.
The arrays looks like this after being created dynamically using an API:
Cities: [object, object, object, object, object, object, object, object, object, object, object, object]
Temperatures: [-2.3, -0.2, -1.2, -25.4, 2.9, -4.8, -2.2, -12.1, 0.3, -5.9, -7.7, -0.1]
How would I do this?
Use an index (assuming temperatures is the array of temperatures defined in the same controller):
<div ng-repeat="city in cities">
<span>City: {{city}} - Temperature: {{temperatures[$index]}}</span>
</div>
you cant use two ng-repeat in one div.
you need a alternative way of doing this, please try this suggestion
<div ng-repeat="city in cities" id={{city.id}}>
<span>{{temperatures[$index]}}</span>
</div>
---- for the best practice
don't use $index its a bad practice but you can achieve what u want in this case.
you can do something like this,
<div ng-repeat="city in cities">
<span>City: {{city}} - Temperature: {{ getTemprature(city) }}</span>
</div>
in controller,
$scope.getTemprature = function(city) {
var index = cities.indexOf(city);
return temperatures[index];
}
because if you use orderBy with the ng-repeat $index will not behave like u assume, $index will get the ordered array $index not the actual array $index.
You can accomplish this with lodash's zip function. Try this:
Controller
$scope.combinedData = _.zip(cities, temperatures);
View
<div ng-repeat="row in combinedData" id="{{row[0].id}}">
<span><b>{{row[0].name}}</b> {{row[1]}}</span>
</div>
Working fiddle: http://jsfiddle.net/hojrhLx5/1/

assign alias to long reference names inside ng-repeat

I would like to be able to assign an alias to a long reference name inside an ng-repeat directive.
Right now I have 2 complex objects, one acts as a kind of grouped index for the other. The ng-repeat template code works fine but it is becoming very difficult to read and I dread the thought of returning to it in a few months time.
If possible, I would like convert something like this:
<div ng-repeat="a in apples">
<div>
<span>Type</span>
<span>{{a.category[1].information.type}}</span>
</div>
<div>
Don't you just love <span>{{a.category[1].information.type}}</span> apples.
My granny says {{a.category[1].information.type}} apples are the best kind.
I would pick {{a.category[1].information.type}} over {{apples[0].category[1].information.type}} apples any day of the week.
</div>
</div>
into something like this
<div ng-repeat="a in apples"
ng-example-assign="ta = a.category[1].information.type">
<div>
<span>Type</span>
<span>{{ta}}</span>
</div>
<div>
Don't you just love <span>{{ta}}</span> apples.
My granny says {{ta}} apples are the best kind.
I would pick {{ta}} over {{apples[0].category[1].information.type}} apples any day of the week.
</div>
</div>
The ng-example-assign directive I made up for this example. Can anyone tell me if something like this is possible using angular or ng-repeat? It may be that I need to rethink the code but I thought I would ask here first. TIA!
You can use ng-init for this:
<div ng-controller="MyCtrl">
<div ng-repeat="s in data" ng-init="address = s.address">
{{ address }}
</div>
</div>
jsfiddle:
http://jsfiddle.net/5yfgLgr9/2/
Using a directive with isolated scope it would be fairly straightforward.
Template HTML
<div assign="ta" source="data[0].items[0].subitems[0]">
Directive
app.directive('assign',function(){
return {
scope:{'assign':'#', "source": '='},
templateUrl: 'testTemplate',
link:function(scope){
scope[scope.assign]=scope.source;
}
}
});
generally a good idea to avoid naming custom directives with ng to avoid possible conflicts with upgrades or third party modules that might also use them
DEMO

AngularJs - Holding value of for loop string to use elsewhere

I've come a bit stuck in my angularjs project.
I run a for loop to query some nested JSON data and output it in 3 different variables inside an ng-repeat. So it makes up a title where i have the control over the elements that make up the title {{ number }} {{ shots }} {{ goals }}.
However, my knowledge of angularjs is stretched here because when I click on one of the events (from the ng-repeat list) it gives me a new tab, but I want to bring the title of that event to the new tab.
I can't call it as a scope variable as the last variable is still being held in there. I thought about assigning it as a new variable.. but was unsure how to actually do that in angularjs.
Here is the code i'm working with:
<li ng-repeat="event in events.events">
<div ng-if="actionType(event)" >
{{number}}
{{shots}}
{{goals}}
</div>
<a class="showPlayer" ng-click="showPlayer(event)">
View more stats
</a>
</li>
my angularjs is just a standard for loop which looks for values inside the js and assigns them as variables.
Any advice is very much appreciated.
EDIT: 24 hours later and I still can't crack this (very frustrating).
I'm not sure if there is a way to grab the string from the ng-click and clone that?
I don't want to have to run another check for the title when I already have the information, surely there is an 'angular' way to do this??
Please try this I am not sure but it might help you
<li ng-repeat="event in events.events">
<div ng-if="actionType(event)" >
{{event.number}}
{{event.shots}}
{{event.goals}}
</div>
<a class="showPlayer" ng-click="showPlayer(event.number,event.shots,event.goals)">
View more stats
</a>
</li>
Try using $rootScope.
Define a rootscope variable where event is handled and write your title in html like you did. {{title}}
$rootScope.title = "example";

Categories