I have a collection and im grouping it using lodash.js groupBy before displaying in the UI using ng-repeat
var list = [{id:1,categoryId:1,name:test1},
{id:2,categoryId:2,name:test2},
{id:3,categoryId:12,name:test12}]
vm.myList= _.groupBy(list,function (j) { return j.categoryId; });
console.debug(vm.myList) // this shows the correct ordering!!!
Now when im displaying it using ng-repeat it messes up the ordering
<div ng-repeat="(categoryId, details) in vm.myList| orderBy: 'categoryId'>
{{ categoryId }}
</div>
this displays
1
12
2
how can I make it to display
1
2
12
I'm trying something like this but no luck
<div ng-repeat="(categoryId, details) in vm.myList| orderBy: 'parseInt(categoryId)'>
{{ categoryId }}
</div>
UPDATE! I found out that this is not an issue in Angular 1.4.x . Unfortunately, we are using old version Angular 1.3.x
first, orderBy filter working only with arrays, so if you try pass object to it, would be returned passed object as is.
second, with ngRepeat
You need to be aware that the JavaScript specification does not define the order of keys returned for an object. (To mitigate this in Angular 1.3 the ngRepeat directive used to sort the keys alphabetically.)
Version 1.4 removed the alphabetic sorting.
If this is not desired, the recommended workaround is to convert your object into an array that is sorted into the order that you prefer before providing it to ngRepeat. You could do this with a filter such as toArrayFilter
So for solving your issue just convert your groupped object to array, and sort it as you want.
Related
I am coding an angular app, that tracks tuxedo rentals.The app contains a table that is populated by an array that I have in the controller.
The first direction I have is to list the items in the table by return date in ascending order. I did this by using the lodash orderBy filter.
The second direction is where I am stuck:
if there are multiple records returned on the same date sort by phone number in ascending order.
I know I can sort the phone numbers, I need help figuring out how I can sort only the ones with the same date(not the entire collection), without altering the order of the return dates.
You can do this much more easily using Angular's sort directive. You can specify multiple sort-by columns, which it does in order.
The syntax is {{ array | orderBy : expression : reverse }} , where you can put an array of order sequence like ['dateReturned', 'phoneNumber'] for the expression argument, and you can also put true or false (or leave it blank) for the reverse argument if you'd like to toggle ASC/DESC
It would look something like this, without a reverse argument:
<tr class="dataRow" ng-repeat="r in vm.rentalRecords track by $index | orderBy:['dateReturned','phoneNumber']">
I´m currentrly trying to filter an array of objects with an search term from an input field.
I know there is a way to apply a search term to an ng-repeat directive using this code ng-repeat="item in list| filter:search_term. But I need to process the filtered list in the JavaScript part of the application. Is there a way how to access the filtered list in the JS part of the application or do I have to choose another approach to filter my array by an search term?
Here is my (currently not working) example code.
EDIT:
I´m searching for a way to do the task completely without using a filter on my ng-repeat! At the end it should be possible to display the filtered list by only using a simple ng-repeat="item in filtered_list
you can use filter in your controller also. Here is your updated fiddle. I hope this can help.
`https://jsfiddle.net/ymcfugzp/3/`
You should filter it inside the Component then.
You can have a function that filters and also does your other processing stuff , similar as the one that follows:
myFilter(term) {
const filtered = list.filter(element => element.term === term);
// Do other stuff in here.
return filtered;
}
Then your template could be as simple as that:
ng-repeat="myFilter(term)"
You can do it like this: ng-repeat="item in filteredList = (list| filter:search_term).
And then just get your filteredList via $scope.filteredList.
Or use controller alias like this:
ng-repeat="item in $ctrl.filteredList = ($ctrl.list| filter:search_term)
- in order to not keep data in $scope
I am writing an angular ng-repeat expression as follows
<tr ng-repeat='instance in instances | filter : search'>
<td>{{$index}}</td>
<td>{{instance.Duration | duration}}</td>
<td>{{instance.Start | mediumDate}}</td>
</tr>
The duration filter is a custom filter that I wrote. It converts the number of seconds to number of days. For example, if instance.Duration is 172800, then the filtered value will be 2 (i.e. 172800/(24*60*60))
Now the problem is, the ng-repeat filter is still applied for the original value(i.e 172800).
How can I make the ng-repeat 'filter' filter to filter results based on the 'duration' filtered results?
Here is a fiddle to show the issue
http://jsfiddle.net/pupudu/00qegfkc/
Create one more object named formattedInstances, which will be copy of Instances, but Duration and Start will be formatted (same format which you get after applying filter). Use this formattedInstances in ng-repeat.
I am using Angular-Translate since I have a website in 2 languages in conjunction with Angular-Material.
To populate my <md-grid-tile> I use ng-repeat a bit differently.
<md-grid-tile ng-repeat="items in tabsCtrl.countProducts track by $index" ...
First I count the amount of arrays in JSON file by getting the value of vm.countProducts variable which I get through this method
JsonData.all(vm.pathToJson[1]).then(function(response) {
vm.namespaceProducts = Object.keys(response.data);
vm.countProducts = JsonData.setObjectCount(Object.keys(response.data[vm.namespaceProducts]).length);
Here is JsonData service method
setObjectCount: function(n) {
return new Array(n);
}
This way, ng-repeat cycles the exact needed amount of times and Angular-Translate populates the values inside.
The problem is that I can no longer use | filter : search on
<input type="text" ng-model="search" ... >
<md-grid-tile ng-repeat="items in tabsCtrl.countProducts track by $index" | filter : search ...
It throws an error since I repeating not an array/object but just numbers
https://docs.angularjs.org/error/filter/notarray?p0=0
Error: filter:notarray Not an array Expected array but received: 0
I am still very new to this whole AngularJS framework, but the error is quite obvious, I need a custom filter. I have no idea though where to start with custom filter, could anyone provide a sample code that would work so I can grasp the idea of where/how to implement it properly.
I host all my code on github https://github.com/Nikki1993/zmed if you need a bigger picture of how I do things (pardon in advance for all the bad code quality, if any, still learning)
Very simple issue I cant seem to resolve, my markup
<select class="testing" ng-model="Car_name" ng-options="item in categories['Car_name']">
I'm trying to change 'Car_name' to be 'car_name' however the server populated the ng-model & categories[] entries, so I'm not sure how I can watch and convert to lowercase in my controller.
If I could do
{{Car_name|lowercase}}
would be the easiest, but not sure on the format.
Option 1
You can do it by using angular.$filter option
Sample look like
<td ng-model={{ lowercase_expression | lowercase}}><td>
$filter('lowercase')()
More details Please see this angular document
Option 2
Please see this below discussion
AngularJS - ngOptions expressions
Option 3
You need to manually add a loop for your array. And convert to the object values to lower case by using toLowerCase() function , and finally push the object to new array.
This is built into AngularJS and can be access via angular.lowercase(string); and then used in your Controller like:
$scope.makeLowerCase = function(string){
return angular.lowercase(string);
};
Now use in your DOM like:
{{Car_name|makeLowerCase}}