Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS orderBy array index

I have an ng-repeat that looks like this:

<div ng-app="questionnaire">
  <div ng-controller="QuestionnaireCtrl">

    <div ng-repeat="(key,val) in questions | orderBy:key">
      {{questions[key].question}}
      {{questions[key].answer}}
    </div>

  </div>
</div>

The controller looks like this:

(function(){
  var app = angular.module('questionnaire',[]);
  app.controller('QuestionnaireCtrl', function($scope){

    $scope.questions = {
      someItem: { question : 'First question' },
      anotherItem: { question : 'Next question here' },
      upgradeItem: { question : 'Another one' }
    };

  });
})();

Now the ng-repeat works fine but displays the questions in a random order. I've tried using orderBy but can't get it working. I just want the questions and answers (which aren't currently in the array) to display in order of index (i.e. the order they're in the array). Alternatively I could add another field 'section' to the array and display them filtered in that order. E.g.

$scope.questions = {
  someItem: { question : 'First question', section : '1' },
  anotherItem: { question : 'Next question here', section : '1' },
  upgradeItem: { question : 'Another one', section : '2' }
};

Fiddle example here: http://jsfiddle.net/k52ez/

like image 894
CaribouCode Avatar asked Aug 04 '14 09:08

CaribouCode


2 Answers

You cannot rely on object order, its not defined. In fact, orderBy filter is supposed to work with arrays only. If you need sorted output you should use array for questions:

$scope.questions = [
    {
        question: 'First question',
        section: 'someItem'
    },
    {
        question: 'Next question here',
        section: 'anotherItem'
    },
    {
        question: 'Another one',
        section: 'upgradeItem'
    }
];

And ngRepeat becomes:

<div ng-repeat="question in questions">{{question.question}} {{question.answer}}</div>

Demo: http://jsfiddle.net/k52ez/2/

like image 103
dfsq Avatar answered Sep 23 '22 12:09

dfsq


I made a custom filter for your problem.

Please see your updated jsfiddle

html:

<div ng-repeat="question in questions | orderByKey">

javascript:

app.filter('orderByKey', [function () {
return function (input) {
    if (!angular.isUndefined(input)) {
        var tmpInput = [];
        angular.forEach(input, function(value, key){
            tmpInput.push(key);
        });
        tmpInput.sort();

        var tmpOutput = [];
        angular.forEach(tmpInput, function(key){
            tmpOutput.push(input[key]);
        });
        return tmpOutput;
    } else {
        return input;
    }
};

There exists also another thread:

https://stackoverflow.com/a/18186947/3641016

but he uses named properties.

like image 44
Raphael Müller Avatar answered Sep 26 '22 12:09

Raphael Müller