0

I have been trying to find an answer for a while and have been unable to do so. I was wondering if anyone had an idea on how to sort the following data (members property) within ng-repeat without using a third party tool.

$scope.element = {
    'sortOrder' : '[0].value' // <-- what is wrong? =[
    'members': [
        [
            { 'name' : 'a', 'value' : 'some' },
            { 'name' : 'b', 'value' : 'value' },
            { 'name' : 'c', 'value' : 'another' },
            { 'name' : 'd', 'value' : 'value' }
        ],
        [
            { 'name' : 'a', 'value' : 'other' },
            { 'name' : 'b', 'value' : 'stuff' },
            { 'name' : 'c', 'value' : 'cats' },
            { 'name' : 'd', 'value' : 'reddit' }
        ],
        [
            { 'name' : 'a', 'value' : 'internets' },
            { 'name' : 'b', 'value' : 'bigdata' },
            { 'name' : 'c', 'value' : 'winwin' },
            { 'name' : 'd', 'value' : 'himom' }
        ]
    ]
}

So, the above data is essentially representing a table. The data can't be restructured for various reasons. Right now I have the following as my markup:

<table class="table">
    <thead>
        <tr>
            <th ng-repeat="key in element.members[0]">
                <a href="#" ng-click="element.sortOrder = '[' + $index + ']' + '.value'">{{ key.name }}</a>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="subelement in element.members | orderBy : element.sortOrder">
            <td ng-repeat="element in subelement" ng-include src="template(element, true)">
            </td>
        </tr>
    </tbody>
</table>

The sortOrder property looks like... it could be correct? I looked at other examples where people had to do this sort of thing (they were using named properties instead of indexes) and I thought I might be getting somewhere, but to no avail.

Any words of enlightenment would be appreciated. Thanks!

1 Answer 1

1

You can't use [0].value with orderBy, the string used with orderBy should be a property of the objects you want to sort. In your case, you want to sort an array of arrays, but [0].value isn't a property of an array, so your approach doesn't work.

However, orderBy can take a "Getter" function to get a value from the object you're sorting, so you can utilize it as follow:

Controller:

$scope.element = {
    sortOrder: -1, // sortOrder is the index, -1 = unsorted
    members: [...]
};

$scope.getValue = function(member) {
    if ($scope.element.sortOrder < 0) {
        return null; // keep members being unsorted
    }
    return member[$scope.element.sortOrder].value;
};

Template:

<table class="table">
    <thead>
        <tr>
            <th ng-repeat="key in element.members[0]">
                <a href="#" ng-click="element.sortOrder = $index">{{ key.name }}</a>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="subelement in element.members | orderBy : getValue">
            <td ng-repeat="element in subelement" ng-include src="template(element, true)">
            </td>
        </tr>
    </tbody>
</table>

Here is an working plunk for you to play with: http://plnkr.co/edit/bebYBCoa6zptOHNLVL9X

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

1 Comment

Thanks man, adding a custom sorting function was the way to go. Wasn't aware of this!

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.