Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular orderBy number sorting as text in ng-repeat

I have this data:

[{"id":"42","firstname":"Sarah","lastname":"Dilby","age":"40","cars":"Yaris"}, {"firstname":"Jason","lastname":"Diry","age":"5","id":"5"}, {"id":"6","firstname":"Bilson","lastname":"Berby","age":"1","cars":"Tipo"}] 

When I orderBy id or by age in an ng-repeat, it sorts the number as text. Since I can't find it written that this is an issue anywhere, I'm guessing there's a problem with my code. I have created this fiddle: http://jsfiddle.net/vsbGH/1/ Sorry about the template, but jsfiddle doesn't allow in the html box. Anyway, this is the code which loads and sorts the data:

//user data app.service('People', function() { var People = {}; People.details = [{"id":"42","firstname":"Sarah","lastname":"Dilby","age":"40","cars":"Yaris"},                   {"firstname":"Jason","lastname":"Diry","age":"5","id":"5"},                   {"id":"6","firstname":"Bilson","lastname":"Berby","age":"1","cars":"Tipo"}] return People; });  //list ctrl controllers.listCtrl = function ($scope,People) {  $scope.people = People.details;   $scope.sortList = function(sortname) {     $scope.sorter = sortname;  } } 

And this is the ng-repeat part of the template:

<tr ng-repeat="person in people | orderBy:sorter ">         <td>{{person.id | number}}</td>         <td>{{person.firstname}} </td>         <td>{{person.lastname}} </td>         <td>{{person.age | number}}</td>         <td>{{person.cars}} </td>  </tr> 

Many thanks if you can help me understand why the number data isn't sorting as numbers, and why it's sorting as text.

like image 570
dewd Avatar asked May 26 '13 22:05

dewd


2 Answers

I think the most appropriate solution is to format the numbers I have on my JSON objects correctly, ie not to wrap them in quotes. So:

 [{"id":"42","firstname":"Sarah","lastname":"Dilby","age":"40","cars":"Yaris"},   {"firstname":"Jason","lastname":"Diry","age":"5","id":"5"},   {"id":"6","firstname":"Bilson","lastname":"Berby","age":"1","cars":"Tipo"}] 

becomes:

[{"id":42,"firstname":"Sarah","lastname":"Dilby","age":40,"cars":"Yaris"},  {"firstname":"Jason","lastname":"Diry","age":5,"id":5},  {"id":6,"firstname":"Bilson","lastname":"Berby","age":1,"cars":"Tipo"}] 

I'm guessing SergL's solution is good if it's not possible to correct the format of the JSON data.

To add to this, the issue in my specific case is to do with PHP's json_encode function on the server side. By default, it treats numbers as strings. To fix I had to add the JSON_NUMERIC_CHECK option to the encode method in the PHP script:

json_encode($assoc_array,JSON_NUMERIC_CHECK); 
like image 108
dewd Avatar answered Sep 25 '22 11:09

dewd


You don't have to modify your JSON. You can pass a function to orderBy filter like this:

$scope.sorterFunc = function(person){     return parseInt(person.id); };  <tr ng-repeat="person in people | orderBy:sorterFunc ">         <td>{{person.id | number}}</td>         <td>{{person.firstname}} </td>         <td>{{person.lastname}} </td>         <td>{{person.age | number}}</td>         <td>{{person.cars}} </td>  </tr> 
like image 30
Ragnar Avatar answered Sep 23 '22 11:09

Ragnar