21

This is the json that is generated using PHP

[{"Sale":{"id":"1","customer_id":"1","amount":"15","created":"2014-05-17"}}]

Doing orderBy:id is obviously not working. I read in other posts that an orderBy function needs to be created for this kind of data structure. I am not able to create the function. Can anyone please tell me what is the correct way to approach this?

2
  • 2
    Read this. Commented May 18, 2014 at 15:23
  • 1
    You don't need to use a custom orderBy function for this. However, as the value of id is a string it will not sort in the order I assume you want. So you might as well put both the sorting and the int conversion in a custom filter just like @Dalorzo suggested. Commented May 18, 2014 at 16:18

3 Answers 3

66

Suppose you have:

$scope.sales = [{"Sale":{"id":"1"}},{"Sale":{"id":"2"}},{"Sale":{"id":"3"}}];

Why not just do following:

<div ng-repeat="sale in sales | orderBy:'Sale.id':true">
    {{ sale.Sale.id }}
</div>

It works well with my case. May be Angular did not support it at the time you asked the question.

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

3 Comments

This is a lot more simple than a custom filter.
The trick is to use | orderBy: 'propertyName.nestedPropertyName', wish the angular docs would mention this syntax.
I improved this method by using a dynamically created property in a controller, that holds the sort field and the sort direction. It looks like this | orderBy:SortController.sort_field:SortController.sort_dir . The SortController gets updated dynamically. So I even can sort by sub nested properties.
5

These type of data manipulations I like to keep them in the proper angular objects and for that reason I would create my custom filter, something like:

var sampleSource=  [{"Sale":{"id":"8","customer_id":"1","amount":"15","created":"2014-05-17"}}, {"Sale":{"id":"5","customer_id":"6","amount":"15","created":"2015-05-17"}}];

var myApp = angular.module('myApp',[]);

myApp.filter('myFilter', function() {
 return function(items) {  
    items.sort(function(a,b){   
        if (parseInt(a.Sale.id) > parseInt(b.Sale.id))
            return 1;
        if (parseInt(a.Sale.id) < parseInt(b.Sale.id))
            return -1;         
        return 0; })
});

Important: I recommend the custom filter because as personal preference I do not like to overload my controllers or other objects with tasks(code) that I can separate on other objects which gives me more independence and cleaner code(one of the things I love about angular) but besides this personal preference I would say that this is not the only way but if you share my reasons behind it I hope it helps.

1 Comment

I used Sergey's link but I will accept your answer.
0
myapp.filter('orderBySub', function () {
  return function (items, field, reverse) {

    byString = function(o, s) {
        s = s.replace(/\[(\w+)\]/g, '.$1');
        s = s.replace(/^\./, '');
        var a = s.split('.');
        for (var i = 0, n = a.length; i < n; ++i) {
            var k = a[i];
            if (k in o) {
                o = o[k];
            } else {
                return;
            }
        }
        return o;
    }

    items.sort(function (a, b) {
        if (byString(a, field) > byString(b, field))
            return reverse ? -1 : 1;
        if (byString(a, field) < byString(b, field))
            return reverse ? 1 : -1;
        return 0;
    })
    return items;
  }
});

Example

ng-repeat="task in tasks | orderBySub: 'field1.subfield2.subsubfield3':true"

true = reverse

Comments

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.