vipulsodha
vipulsodha

Reputation: 25

AngularJs dynamic orderBy expression

Below is the code. I have nested ng-repeat and a field that has sum of all other fields.

<div class="animate margin-top" >
        <div layout="row" layout-align="center"  ng-repeat="data in leaderBoardData | orderBy: 'getTotal($index)'" style = "padding: 10px;" class= "md-padding">
            <section class="text-center width-20"><a>{{data.handleName}}</a></section>
            <section class="text-center width-20" ng-repeat="score in data.score track by $index">{{score}}</section>
            <section class="text-center width-20">{{getTotal($index)}}</section>
        </div>
</div>

So I want to sort it according to the dynamic field getTotal($index). How should I do it? the above orderBy is not working.

Below is code for getTotal() function

$scope.getTotal = function (index) {
    var total = 0
    $scope.leaderBoardData[index].score.forEach(function (score) {
        total = total + score
    })
    return total
}

Below is leaderboardData

var leaderBoardData = [ { handleName: 'xyz', score: [1,2,3] },{ handleName: 'acc', score: [4,5,6] } ]

Upvotes: 2

Views: 3582

Answers (4)

user5056311
user5056311

Reputation: 169

  1. remove the quotes for orderBy expression, so angular knows it's a function, you don't need to explicitly pass $index as an argument.

  2. you need to change this {{getTotal($index)}} to {{getTotal(data)}} as data is already iterated in here.

so, basically:

function Ctrl($scope) {

  $scope.leaderBoardData = [{
    handleName: 'xyz',
    score: [4, 5, 6]
  }, {
    handleName: 'acc',
    score: [1, 2, 3]
  }, {
    handleName: 'acFc',
    score: [1, 2, 4]
  }];

  $scope.getTotal = function(index) {
    var total = 0;
    // also change to index as array already passed to function
    index.score.forEach(function(score) {
      total = total + score;
    })
    return total;
  };
}
<!DOCTYPE html>
<html ng-app>

<head></head>

<body>
  <div>
    <div ng-controller="Ctrl" class="animate margin-top">
      <div layout="row" layout-align="center" ng-repeat="data in leaderBoardData | orderBy: getTotal" style="padding: 10px;" class="md-padding">
        <section class="text-center width-20">
          <a>{{data.handleName}}</a>
        </section>
        <section class="text-center width-20" ng-repeat="score in data.score track by $index">{{score}}</section>
        <section class="text-center width-20">
          <!-- change is here -->
          {{getTotal(data)}}
        </section>
      </div>
    </div>
  </div>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</body>

</html>

Upvotes: 1

RIYAJ KHAN
RIYAJ KHAN

Reputation: 15292

you can do it in this way. HTML

<div layout="row" layout-align="center"  ng-repeat="data in leaderBoardData | orderBy: 'totalScore'" style = "padding: 10px;" class= "md-padding">
            <section class="text-center width-20"><a>{{data.handleName}}</a></section>
            <section class="text-center width-20" ng-repeat="score in data.score track by $index">{{score}}</section>
            <section class="text-center width-20">total score={{data.totalScore}}</section>
        </div>

JS :

$scope.leaderBoardData =  [ { handleName: 'xyz', score: [111,21,3] },{ handleName: 'acc', score: [14,5,16] } ];

     $scope.leaderBoardData.forEach(function(oneRecord,key){
        var total=0;
        oneRecord.score.forEach(function(oneEle,key){
            total = total + oneEle

        })
        oneRecord.totalScore = total;

     })

Upvotes: 0

Anant Maheshwari
Anant Maheshwari

Reputation: 3

I'm guessing you're not using forEach correctly.

    $scope.getTotal = function (index) {
    var total = 0;
    angular.forEach($scope.leaderBoardData,function(score,index){
        total = total + score
    })
    return total;
}

Try this and it should work.

Upvotes: 0

gandharv garg
gandharv garg

Reputation: 2181

I am guessing that $scope.leaderBoardData isn't an array (it's an object of objects), and the orderBy filter only works with arrays. If you make $scope.leaderBoardData an array, it will work

Upvotes: 0

Related Questions