Angular orderby sorting in loaded orders - angularjs

By using ng-repeat i'm getting values but i need to sort it in specific order.
that is 'Portfolio', 'Sourcing', 'Delinquency'
can you please help me by providing sorting order.
HTML:
ng-repeat="row in DashboardFilter2" | orderBy: ['Portfolio', 'Sourcing', 'Delinquency']
js:
App.createList({
"qDef": {
"qFieldDefs": %Type
},
"qInitialDataFetch": [
{
"qHeight": 20,
"qWidth": 1
}
],
},function Show2(reply, app){
$scope.DashboardFilter2 = app.field("%Type").getData();
});

ng-repeat looks correct to me.
Would be good to see app.field("%Type").getData() result.
But to be honest, I would not use orderBy with strong reason since it is a filter and evaluates on every $digest/$apply.
Instead, I'd sort as I want in JS before putting it into template using Array.sort or similar method (lodash, underscore).
If the array changes after initialization then just make a function sortArrayYouWant and call every time it changes.
The global idea is NOT TO USE ORDERBY since it is extremely inefficient

Related

Angularjs: Ng-repeat and unique filter in array

I have a set of data like this
$scope.students = [
{ name:"John", courses:["Math", "Physics", "Chemistry"] },
{ name:"Paul", courses:["Economics", "Math", "Sociology"] }
]
I would like a way to filter using angular-filter so that I can get a list of all the subjects without repetition.
I've been trying to use unique filter, but I cannot get it to work since I try to iterate like
<ul ng-repeat="student in students">
<li ng-repeat="x in student.courses | unique:courses"></li>
{{x}}
</ul>
My desired output of the first ng-repeat would be an array like this:
["Math", "Physics", "Chemistry", "Economics", "Sociology"]
so I could iterate through it in the second one.
I have achieved this throught making a new scope with just the desired array, but then I cannot bind it properly, so I would like to achieve it through filtering. Thanks in advance.
I would really recommend you using the libraries Lodash or Underscore for this kind of problems. Learning to master these has helped me a lot!
Of course, you can create your own angular filter using one of them. The method you would like to use is union:
_.union(_.flatten(_($scope.students).pluck("courses")))
I use pluck to get out the courses arrays from the studens object, then I flatten the result (to get rid of the array that it comes nested in), and then i use union to get each subject only once.
If the requirement actually is to:
...get a list of all the subjects without repetition.
Then I would make a separate array for subjects:
$scope.courses = [];
// There are many ways to do skin this cat... (prograde does have a point!)
$scope.students.forEach(function(student) {
student.courses.forEach(function(course) {
if ( $scope.courses.indexOf(course) === -1 ) {
$scope.courses.push(course);
}
})
});
HTML
<ul>
<li ng-repeat="course in courses">
{{ course }}
</li>
</ul>
And if the students change I would recreate the courses-array.
But it sounds as if you are trying to do something else.
But it doesn't give the desired output.
It would help if you tell us what that desired output is!
http://plnkr.co/edit/bZNjIEFznvuyTU3zxAp1?p=preview

angularjs - track by in a for loop

I have a problem with the refresh button in my Angular application:
I have a json object with two arrays in it -> data = {array1: [], array2: []}
I want to loop both arrays and print the related values. To achieve that, I use the Angular ng-repeat directive like this:
ng-repeat="index in [] | index:getTotalNumberOfObjectsInArray1()"
...
<span ng-bind="data.array1[index]"></span>
<span ng-bind="data.array2[index]"></span>`
My Problem is, that on every click on the refresh-button these data will be recreated on the dom.
I learned the documentation about "track by" but i understand it only on objects (for example: ng-repeat="a in objects track by a.id")
How can I use this track by filter for my ng-repeat above, to prevent the recreation of my data?
You can use $index that is defined in a ng-repeat (cf.doc) but you have to have the two array with the same length.
Another solution could be to merge your arrays together and loop on it but I am not sure if it answer to your question.

Display one item from array in AngularJS without using ng-repeat

I have JSON array like:
var data = [
{
"name": "Jim",
"age" : 25
},
{
"name": "Jerry",
"age": 27
}
];
in HTML:
<ul>
<li ng-repeat="val in data | filter:{age: age}:true">{{val.name}}</li>
</ul>
The above code is working fine as i want the output, but i don't want to use ng-repeat where it creates loop and then i filter.
is there any another way where i can directly select the DATA from array where age = age ??
Filters can be used in any angular expression (there is nothing ngRepeat-specific about them).
(They can be even used in JavaScript.)
E.g. the following expression displays the data associated with the first user (limitTo:1) that has an age of 25 (filter:{age: 25}), formatted as JSON (json):
{{data | filter:{age: 25}:true | limitTo:1 | json}}
See, also, this short demo.
As mentioned by #link in comments, there is no way to pluck the object with the required age from the array without looping through it. However, you're right in thinking that using ng-repeat here is not appropriate if you only want to display a single object from the array, so ideally the required object should be stored in your controller.
One approach would be to use $filter in your controller instead:
$scope.obj_with_correct_age = $filter("filter")(data, {age: age});
<li>{{ obj_with_correct_age.name }}</li>
I realize this is an old thread but for completeness.
This works:
{{data.Systems[data.Detail.SystemId].System}}
This way, you don't need to filter the data.
If you want to parse single value of name. like {"name":"value"}.
so after $http post, i am assuming that your response in var data= response.
Now find, like console.log(data[0].name);
Here, result will be Jim

unshifting to ng-repeat array not working while using orderBy

Here is my problem. I've got a comment roll thats using ng-repeat to display the content of a comment array. When the user submits a comment I wan't to unshift to that array in order to display the most recent comment at the top of the list. This works perfectly, but when I add the orderBy filter to the repeat the new comment is applied to the bottom of the repeat.
Here is the comment array HTML:
<ul ng-repeat="comment in comments | filter:{page_id:raceID} | orderBy:'id':'reverse' track by comment.id ">
<li>{{comment.id}}</li>
<li>{{comment.page_id}}</li>
<li>{{comment.user_name}}</li>
<li>{{comment.comment_copy}}</li>
</ul>
Here is the corresponding Controller:
$scope.comment = new newComments({page_id:3, comment_copy:'test comment copy'});
$scope.comment.$save(function(data) {
$scope.comments.unshift($scope.comment);
console.log($scope.comment.id);
});
.....
I scrapped the
orderBy:'id':'reverse'
and instead used a custom filer left on another post here, Angular ng-repeat in reverse. Here is the custom function
app.filter('reverse', function() {
return function(items) {
return items.slice().reverse();
};
});
Now the most recent comment was still not showing up at the top of the page so I had to change from unshift to push. This worked perfectly. Here's the code:
$scope.comment.$save(function(data) {
$scope.comments.push($scope.comment);
});
A few things are wrong in your original post:
orderBy:'id':'reverse' should be orderBy:'id':reverse, where reverse is a boolean (so either replace it by a variable available on the scope, or by a hard-coded true/false). Currently, it defaults to undefined and is interpreted as false.
In your controller code, the field comment.id is not assigned. It will default to undefined and that's the reason sorting does not work as expected.
Additionally:
Array unshift or push will not make a difference in your use case if you correct the aforementioned and the orderBy function is invoked.
In my experience in Angular 1.5.8, track by $index in fact prevented the orderBy function from working. Replacing it by a unique identifier on the object to be repeated, i.e. track by comment.id is preferred. In terms of performance, they should be analogous. Not using the track by clause is the slowest option though. (https://docs.angularjs.org/api/ng/directive/ngRepeat)
that worked for me, would love to know how it affects performance though:
change:
track by comment.id
to:
track by $index
both unshift() and push() should work now, but again, not sure about how much it slows down the DOM regeneration.

AngularJS orderBy function being ignored in ng-repeat

The orderBy function is being completely ignored. I've added a console.log at one point for testing and the function isn't even being called. The data is still displayed but is unordered.
HTML Code
<div id="tabs">
<a ng-repeat="tab in tabs | orderBy:tabordinal" id="tab-{{tab.tab_id}}" class="{{getClasses(tab)}}" ng-click="tabclick(tab)">{{tab.label}}</a>
</div>
JS Function
$scope.tabordinal = function (tab) {
return $scope.taborder.indexOf(tab.tab_id);
};
Everything else is set up correctly, (i.e. ng-click's work properly, the data is bound properly, and filters are working on the other elements.
A few things...
orderBy takes a string, or an expression that returns a string. That string should be the name of a property you want to order by on the list of objects you're ordering. So if the objects in your array have properties like [ { 0: 'foo', 1: 'bar', '2': 'blah' } ], then you're good to go, I guess. But I doubt they're structured like that.
orderBy:tabOrdinal() if your expression is a function, as yours is in the original post, you need that ().
Outside of that, if you provide a fiddle, I can give you more help.

Resources