orderBy in ngRepeat using another variable property - angularjs

Is it possible to sort items from one array based on another variable by only using orderBy and not adding a count property to the items in the array?
Lets say i have an array and a map in the controller:
$scope.x = [{no:1,name:"a"},
{no:2,name:"b"},
{no:3,name:"c"}];
$scope.y = { 1: [1],
2: [1,2,3],
3: [1,2] };
and the html will look like this:
<div ng-repeat="i in x | orderBy: y[i.no].length">
{{i.no}}
{{ y[i.no] }}
{{ y[i.no].length }}
</div>
output:
1 [1] 1
2 [1,2,3] 3
3 [1,2] 2
but it should be:
1 [1] 1
3 [1,2] 2
2 [1,2,3] 3

You could use a predicate function, to specify your condition.
Try this:
<div ng-repeat="i in x | orderBy: findOrder">
{{i.no}}
{{ y[i.no] }}
{{ y[i.no].length }}
</div>
And:
$scope.findOrder = function(elem){
console.log(elem.no);
return $scope.y[elem.no].length;
}
A working fiddle.

Related

Angular ngFor out of order

I have an array of months. for some reason angular for loop does not follow the order of the array.
How can that be fixed?
#Component({
selector: 'my-app',
template: `<div *ngFor="let item of collection | keyvalue; index as i">{{item | json}}</div>`,
})
export class AppComponent {
collection : {key : any, value : any}[] = [];
constructor(){
let i = 0;
for(let month of moment().locale('en-US').localeData().monthsShort()){
i++;
this.collection.push({key : i,value : month});
}
}
https://stackblitz.com/edit/angular-i25npn?file=src%2Fapp%2Fapp.component.ts
According to the definition of keyvalue from the docs.
The output array will be ordered by keys. By default the comparator
will be by Unicode point value...
And therefore your keys(string) are ordered by default.
Remove the pipe | keyvalue; index as i from your *ngFor.
To follow the order, replace:
<div *ngFor="let item of collection | keyvalue; index as i">{{item | json}}</div>
by:
<div *ngFor="let item of collection">{{item | json}}</div>

How to handle filter in Angular expression

Please have a look at below code
Json object
namelist = [{name: "Mayur" , checked : true }, { name: "Rayum" , checked : false }]
In HTML i want to show number of items which are checked true , for above Json object count should be 1.
{{namelist.length}} // gives me total count
//can we do something like below
{{ namelist.length | filter {checked:true} }}
which we give me only count of the filtered count.
Try this:
{{ (namelist | filter: { checked: true }).length }}
Try this: {{ (namelist | filter:{checked:true}).length }}
You can read about filters here

ng-repeat orderBy not working with Boolean? [duplicate]

I'd like to be able to sort by whether a variable is true or false.
Let's say we have a variable like so:
groups = {
{ name: 'first', value: true },
{ name: 'second', value: false },
{ name: 'third', value: true },
{ name: 'fourth', value: false }
}
And we can loop through it like so:
<div ng-repeat="group in groups">
{{group.name}} {{group.value}}
</div>
Which will give you the following:
first true
second false
third true
fourth false
But if I wanted to sort by a boolean value then I could do this:
<div ng-repeat="group in groups | filter:{value:true}">
{{group.name}} {{group.value}}
</div>
<div ng-repeat="group in groups | filter:{value:false}">
{{group.name}} {{group.value}}
</div>
Which would give me the following output (which I want):
first true
third true
second false
fourth false
Is there a way to do this using orderBy or filter in a single ng-repeat?
orderBy accepts and sorts by booleans.
Order the repeated element by the the 'value' property of 'group':
ng-repeat="group in groups | orderBy: 'value'"
This will reverse the order:
ng-repeat="group in groups | orderBy: '-value'"
If you would like to also sort by the 'name' property of 'group':
ng-repeat="group in groups | orderBy: ['value','name']"
use variable name instead obeject
orderBy:'Event':false
you will get the desired output like -
first true
third true
second false
fourth false

AngularJS toArray converts object keys to numbers

I use angular-filter in my project to sort the output objects by page the problem is when I use syntax like this:
<ul class="catalog-list"
ng-repeat="(key, value) in list | groupBy: 'styl' | toArray | orderBy:'page'">
{{key}}
<li ng-repeat="dziecko in value | filter:search | bookmark:search"
ng-class="{active:isActiveTab(dziecko)}"
ng-click="openItem(dziecko)">
{{dziecko.rodzina}}
<b>{{dziecko.page}}</b>
</li>
</ul>
Angular converts 'styl' properties ['nowoczesny','klasyczny'..] to numbers. Sorting works fine but I want to obtain names instead of numbers.
groupBy return an object, and orderBy expect array as an argument, so that's the reason you should use toArray filter.
toArray work like that:
Usage: object | toArray: addKey[optional]
if addKey set to true, the filter also attaches a new property $key to the value containing the original key that was used in the object we are iterating over to reference the property
So, you can do something like this example, or take a look on the jsbin
JS:
$scope.groups = [
{ category: 'alpha', id: 2 },
{ category: 'beta', id: 3 },
{ category: 'gamma', id: 0 },
{ category: 'alpha', id: 4 },
{ category: 'beta', id: 5 },
{ category: 'gamma', id: 1 }
];
HTML:
<ul ng-repeat="group in groups | groupBy:'category' | toArray:true | orderBy:min">
<!-- print the group name -->
<li>{{ group.$key }}</li>
<!-- iterate over the group members and order each group by id -->
<li ng-repeat="item in group | orderBy:'id'">
{{ item }}
</li>
</ul>
RESULT:
alpha
{"category":"alpha","id":2}
{"category":"alpha","id":4}
beta
{"category":"beta","id":3}
{"category":"beta","id":5}
gamma
{"category":"gamma","id":0}
{"category":"gamma","id":1}
An array has no named keys. It has integers as position. So don't use toArray.

Nested ng repeat, natural sorting keys

I have data which can take the following format:
var data =
{
0:[1:"a", 2:"b", 11:"c", 22:"d"],
1:[1:"e",2:"f",11:"g",22:"h"]
}
If I do the following:
<div ng-repeat="(key, value) in data">
<div ng-repeat="(innerKey, innerValue) in value">
{{innerKey}}
</div>
<br/>
</div>
This will give me:
1 11 2 22
1 11 2 22
since it is sorting by string comparison on the keys, not the numeric value of the key
What I really want is:
1 2 11 22
1 2 11 22
Any suggestions?
If you could restructure the data a little bit, you could try this. I removed the nested data to simplify the core issue.
http://jsfiddle.net/rsmclaug/BHF9C/
Also, the data as-is is not valid array syntax.
<div ng-repeat="item in data | orderBy:'key'">
{{item.key}} - {{item.value}}
</div>
$scope.data = [
{key: 1, value: "a"},
{key: 12, value: "c"},
{key: 2, value: "b"},
{key: 22, value:"d"}
];

Resources