5

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/

CaribouCode
  • 13,998
  • 28
  • 102
  • 174

3 Answers3

3

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/

dfsq
  • 191,768
  • 25
  • 236
  • 258
  • Just noticed you've changed the array structure. Each index in the array is named, which seems to be what's causing the issues. That is why I was initially using key and value in the repeat. Removing the array names is not an option. Would you be able to edit your answer to accommodate? I can't seem to get your solution working with the correct array. – CaribouCode Aug 04 '14 at 09:36
  • Using object like you do will not allow you to order output. You should use array, not object. – dfsq Aug 04 '14 at 09:43
3

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.

Community
  • 1
  • 1
Raphael Müller
  • 2,180
  • 2
  • 15
  • 20
1

The AngularJS Documentation on this matter is precise and fits your exact usecase. ReadTheDocs

Gathering your questions in an Object seems to be a strange thing to do. Objects have no order in their attributes so ngRepeat shouldn't know either. Instead you might want to put your questions into an ordered data structure like an array.

I updated your fiddle with an orderBy expression on a key Field in your Objects.

JS:

$scope.questions = [
    {question : 'First question' , key: 3},
    { question : 'Next question here',  key: 2},
    { question : 'Another one', key: 1 }
];

HTML:

<div ng-repeat="question in questions | orderBy:'key'">

Fiddle

Christoph Hegemann
  • 1,434
  • 8
  • 13
  • 2
    I just spent a long time looking at the Angular Docs and couldn't get it working for me, so came to Stackoverflow. This is not an answer so do not present it as one. It's people like you that ruin these communities spending time picking holes in questions rather than providing useful answers. – CaribouCode Aug 04 '14 at 09:21
  • Okay im sorry. I'll Edit my answer – Christoph Hegemann Aug 04 '14 at 09:22