Why $index is zero if object has index 1? - angularjs

I have object data.specialization.all:
{"1":{"name":"AilÉ™","checked":false,"id":"6"}}
And ng-repeat:
ng-repeat="(key, value) in data.specialization.all | orderObjectBy : 'value.name' : true"
Inside ng-repeat I display key:
{{key}}
And get zero (0)
Why if I have index 1 in object?

I believe the issue is with your filter:
orderObjectBy : 'value.name' : true"
Basically, the return of that is an enumerable list instead of a dictionary. You're getting the index of the first element of that list, not the key to your dictionary.

This jsbin shows the correct key.
http://jsbin.com/mirisixodo/edit?html,js,output
The issue appears to be in your filter. Could you post that code?

Related

ng-repeat value in array with same name

In my array there is multiple key value having same name . I want to list them all in my View how can I achieve that ?
I am facing error stating [ngRepeat:dupes] Duplicates in a repeater are not allowed.
This is my JSON array :-
["text-align", "space-before", "space-before.conditionality", "font-size", "font-weight", "line-height", "font-size", "font-weight", "line-height", "space-before", "font-size", "font-weight", "line-height", "position", "top", "bottom", "right", "left", "text-align", "force-page-count", "break-before", "font-size"]
As we can see few keys are repeating . I need to list all repeated values without missing any in my View
You you use ng-repeat it loops over the unique values in the array. If you have duplicate values then you need to explicitly mention the Angular module to ignore the values to be unique and look for unique index value, by doing:
ng-repeat = "item in items track by $index"
Using track by you can explicitly mention that which value should be checked as a uniqueness measure while rendering the DOM using ng-repeat. You can even use the property of the object like item in items track by item.id where item is a object having id property and items is a array of objects.
Your array has font-size specified multiple times in the array so use track by $index.
You can use track by $index to remove this error, something like this
<tag ng-repeat="item in items track by $index">
//content
</tag>
https://docs.angularjs.org/api/ng/directive/ngRepeat

I want to get the index of ng-repeat

<div ng-mouseenter="$ctrl.clicker($ctrl.adherence.events[$index].id)">
<scheduled-event
event="event"
ng-repeat="event in $ctrl.adherence.events">
</scheduled-event>
In the code I want to use the index of ng-repeat to get the index of an array however my index value using $index is not retreiving this value.
seems like you want to capture the $index and then fire your function based on that.
You can have an
ng-click="clickFunction($index)"
and then have that function do rest of the work.

AngularJS ng-repeat with filter - notarray error

I have a list of items that I'm displaying with ng-repeat. I want to add a filter to show/hide archived items.
I have added a checkbox:
<input type="checkbox" ng-model="queryFilter.archived">Show archived messages
In my controller I have this:
$scope.queryFilter = {
archived: false
};
My list of items is displayed in a table. I've tried the following:
<tr ng-repeat="message in messages | filter : queryFilter">
<tr ng-repeat="message in messages | filter : { archived: queryFilter.archived }">
<tr ng-repeat="message in messages | filter : queryFilter track by $index">
I get this error:
Error: [filter:notarray]
Expected array but received: {}
The filtering does work but I want to know why I am getting the error.
I had initialised messages as an object.
Changing $scope.messages = {}; to $scope.messages = []; made the error go away.
Your messages must be containing the data in Object form not in the Array form.
That is why this error is being thrown. Check the doc https://docs.angularjs.org/error/filter/notarray
From the docs:
Filter must be used with an array so a subset of items can be
returned. The array can be initialized asynchronously and therefore
null or undefined won't throw this error.
So make sure, your $scope.messages containing data in array form not in the Object form.
The track by $ index makes angular syntax incorrect, since it is directly positioned behind the filter instruction. Try moving it behind the repeat statement so there is a clear separation between the track by and filter statements.
<tr ng-repeat="message in messages | filter : queryFilter track by $index">
queryfilter is an object not an array. So apply the ng-repeat on queryfilter as given below
<tr ng-repeat = "message in messages | filter : queryFilter track by $index">
if queryfilter is array then simply use
<tr ng-repeat = "message in messages | filter : queryFilter">
track by $index is necessary whenever we loop the object

Filtering an Angular 1.2 ng-repeat with "track by" by a boolean property

I'm trying to filter some list items based on the value of a boolean property, but no matter what I do the entire list is always displayed. A few of the the things I've tried have been so broken that nothing displays, but that's neither here nor there. I can't get my filtering working as desired:
$scope.attendees = [
{"firstname":"Steve", "lastname":"Jobs", "arrived":true, "id":1}
,{"firstname":"Michelle", "lastname":"Jobs", "arrived":false, "id":2}
,{"firstname":"Adam", "lastname":"Smith", "arrived":true, "id":3}
,{"firstname":"Megan", "lastname":"Smith", "arrived":false, "id":4}
,{"firstname":"Dylan", "lastname":"Smith", "arrived":false, "id":5}
,{"firstname":"Ethan", "lastname":"Smith", "arrived":false, "id":6}
];
Using the following ng-repeat filtering:
<ul>
<li ng-repeat="person in attendees track by person.id | filter:arrived:'false'">
{{person.lastname}}, {{person.firstname}}
</li>
</ul>
I feel like I've tried every permutation that I can find referenced, most of which came from various StackOverflow search results:
filter:'arrived'
filter:arrived
filter:'person.arrived'
filter:person.arrived
filter:{arrived:true}
filter:{arrived:'true'}
filter:{person.arrived:true}
filter:{person.arrived:'true'}
I've also tried creating a custom filter function:
$scope.isArrived = function(item) {
return item.arrived;
};
And applying it thusly:
filter:isArrived
filter:'isArrived'
filter:{isArrived(person)}
filter:isArrived(person)
filter:'isArrived(person)'
None of these seems to work. What am I missing?
Here's a plnkr that demonstrates my problem.
The track by needs to be at the end of the expression:
<li ng-repeat="person in attendees | filter: {arrived: false } track by person.id">
#Gruff's answer is right, but just to give an answer from an official source:
From the Angular ng-repeat docs:
Note: track by must always be the last expression:
<div ng-repeat="model in collection | orderBy: 'id' as filtered_result track by model.id">
{{model.name}}
</div>
It also appear on the "Arguments" part of the docs:
Note that the tracking expression must come last, after any filters,
and the alias expression.

Number of items in a list filtered AngularJS

How do you get the length/number of items returned by a filter predictate in AngularJS?
I managed to find a great answer on the AngularJS Google Group, thanks to Pawel Kozlowski.
ng-repeat="item in filtered = (items | filter:filterExpr)"
Would create the filtered list on the fly, you can use filtered.length anywhere else in the current scope to show the count.
Solution
Try this :
HTML
<span ng-bind="nb"></span>
Javascript
$scope.nb = $filter('filter')(items, filterExpr).length;
Documentation
In HTML Template Binding
{{ filter_expression | filter : array : expression : comparator}}
In JavaScript
$filter('filter')(array, expression, comparator)
i also had to display the length of a filtered array and this one worked for me:
{{ (items | filter:filterExpr).length }}
As a matter of facts, this will work with display filter(orderBy, limitTo)
item in list = ( item_array|filter:some_str) | orderBy: pref | limitTo: nItemToDisplay
if you need to display 5 items at a time, you still can use list.length. Usefull for pagination or in datatable.

Resources