3

I've seen lots of answers and documentation indicating that you can pass an array of attribute names to Angular's orderBy filter to sort by multiple fields. However, one of my object attributes is a number stored as text (field can be "100", "75", "50", or "<25"). In order to sort these values as numbers, I have been using:

<div ng-repeat="item in items | orderBy:sortFunction">
   {{item.itemStatus}} - {{item.itemLevel}}
</div>

//Function in controller...
$scope.sortFunction = function(item) {
   return parseInt(item.itemLevel);
}

What I want to do now is sort first by item.itemStatus, then by item.itemLevel as a number. Is there a way to do that without first changing my data model? I could loop through all items and add a new attribute that is the itemLevel as a number, then filter using

 ng-repeat="item in items | orderBy:['itemStatus','itemLevelAsNumber']

but I would like to know if there's a better way to do it. I have tried

 ng-repeat="item in items | orderBy:['itemStatus',sortFunction]

but I think using a function in that scenario expects to have the attribute name returned as a string.

Thanks!

4
  • Have you checked stackoverflow.com/questions/17037524/… Commented May 8, 2017 at 14:30
  • I don't have an answer for doing a secondary sort but I did want to point out that custom comparator functions take two parameters because the function needs to do a comparison between two elements of the collection. You then have to return 0 if the two items are equal, -1 if the first value is less than the second and 1 if the first item is greater than the second. docs.angularjs.org/api/ng/filter/orderBy Commented May 8, 2017 at 14:34
  • but I think using a function in that scenario expects to have the attribute name returned as a string. Nope, it works the same way as in your first example.Look at the documentation so item in items | orderBy:['itemStatus',sortFunction] should be fine. Proved by this fiddle Commented May 8, 2017 at 14:34
  • @George - You're right. My issue was that parseInt("<25") actually returns NaN, not 25. I guess parseInt will ignore text following a valid number, but not the other way around. Commented May 8, 2017 at 15:36

1 Answer 1

1

Issue was with my sortFunction. I didn't realize that parseInt will only extract the number from a mixed value if the number is first.

 parseInt("25") === 25; //true
 parseInt("25+") === 25; //true
 parseInt("<25") === 25; //false - actually returns NaN

I updated the sortFunction to

 return parseInt(item.itemLevel.replace('<',''));

and the multi-level orderBy in the view is what I thought it should be now:

 ng-repeat="item in items | orderBy:['itemStatus',sortFunction]

Thanks for the comments!

Sign up to request clarification or add additional context in comments.

1 Comment

I would recommend using Regex for you replace as if you use this is in the future it's a bit more robust. Glad you solved your problem and thank you for posting the answer here instead of just keeping it to yourself!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.