iCode
iCode

Reputation: 9202

AngularJS Order JSON array and inner arrays

Hi In my Controller from Server I am getting a JSON String

$scope.unsorted=data;

And the data looks like

[
  {
    "configId": 116,
    "configName": "LAND_LINE",
    "configFieldses": [
      {
        "FieldId": 784,
        "FieldName": "engine.form.1",
        "values": [
          {
            "keyname": "formName",
            "value": "Account Number",
            "id": 3068
          },
          {
            "keyname": "formValuePosition",
            "value": "right",
            "id": 3069
          }
        ]
      },
      {
        "FieldId": 783,
        "FieldName": "engine.form.0",
        "values": [
          {
            "keyname": "formName",
            "value": "Amount",
            "id": 3074
          },
          {
            "keyname": "formValuePosition",
            "value": "right",
            "id": 3075
          },
          {
            "keyname": "regexGazatteer",
            "value": "Total Charges :",
            "id": 3076
          }
        ]
      },
      {
    "FieldId": 785,
        "FieldName": "engine.table2",
        "values": [
          {
            "keyname": "regexTableHeaderStart",
            "value": null,
            "id": 3079
          },
          {
            "keyname": "regexTableBodyEnd",
            "value": null,
            "id": 3080
          },
          {
            "keyname": "tableName",
            "value": "invoice",
            "id": 3078
          }
        ]
      }
    ]
  }
]

I want to sort the configFieldses array based on FieldId and also the values array in each configFieldses based on id. So the JSON should looks like

[
  {
    "configId": 116,
    "configName": "LAND_LINE",
    "configFieldses": [
      {
        "FieldId": 783,
        "FieldName": "engine.form.0",
        "values": [
          {
            "keyname": "formName",
            "value": "Amount",
            "id": 3074
          },
          {
            "keyname": "formValuePosition",
            "value": "right",
            "id": 3075
          },
          {
            "keyname": "regexGazatteer",
            "value": "Total Charges :",
            "id": 3076
          }
        ]
      },
      {
        "FieldId": 784,
        "FieldName": "engine.form.1",
        "values": [
          {
            "keyname": "formName",
            "value": "Account Number",
            "id": 3068
          },
          {
            "keyname": "formValuePosition",
            "value": "right",
            "id": 3069
          }
        ]
      },

      {
    "FieldId": 785,
        "FieldName": "engine.table2",
        "values": [
          {
            "keyname": "tableName",
            "value": "invoice",
            "id": 3078
          }
          {
            "keyname": "regexTableHeaderStart",
            "value": null,
            "id": 3079
          },
          {
            "keyname": "regexTableBodyEnd",
            "value": null,
            "id": 3080
          }
        ]
      }
    ]
  }
]

What I have tried is first sort the parent array and then the child arrays.

var sortedfieldses = orderByFilter($scope.unsorted.configFieldses, '+FieldId');

But then How to remoive the old array from unsorted config and add the new to unsorted. And also how to loop through each and then sort it?

What is the best way?

Upvotes: 0

Views: 2068

Answers (2)

Kelvin Yong
Kelvin Yong

Reputation: 118

If you only need to sort the array, you could do this

    $scope.unsorted=data;

    // sort the parent
    $scope.unsorted[0].configFieldses.sort(function(config1, config2) {
        return config1.FieldId - config2.FieldId;
    });

    // sort the child values
    $scope.unsorted[0].configFieldses.forEach(function(configField){
        console.log(configField.values);

        configField.values.sort(function(value1, value2) {
            return value1.id - value2.id;
        });

    });

But if you want to display the the data using ng-repeat and orderBy filters, you could do use a nested ng-repeat like so.

    <div ng-controller="ControllerX">
        <div ng-repeat="configField in unsorted[0].configFieldses | orderBy:'FieldId' ">
            <h3>{{configField.FieldId}}, {{configField.FieldName}}</h3>
            <ul>
                <li ng-repeat="value in configField.values | orderBy:'id'">
                    {{value.id}}, {{value.keyname}}
                </li>
            </ul>
        </div>
    </div>

Upvotes: 0

Tom McQuarrie
Tom McQuarrie

Reputation: 1147

Step 1: copy the object, then apply a custom sort function.

var sortedfieldses = angular.copy( $scope.unsorted.configFieldses );

sortedfieldses.sort( function( a, b ){
    return a.FieldId > b.FieldId;
});

Step 2: Iterate through the "fieldses" and sort their children:

angular.forEach( sortedfieldses, function( field, key ){

    field.values.sort( function( a, b ){
        return a.id > b.id;
    });
});

Actually re-reading your question, it sounds as though you just want to sort the 'unsorted' object in-place, rather than copying to a 'sorted' variable. If that's the case, skip the object copying and just do:

$scope.unsorted.configFieldses.sort( function( a, b ){
    return a.FieldId > b.FieldId;
});

angular.forEach( $scope.unsorted.configFieldses, function( field, key ){

    field.values.sort( function( a, b ){
        return a.id > b.id;
    });
});

The sort method alters the original array, rather than simply returning the sorted copy.

Upvotes: 2

Related Questions