4

I'm new to AngularJS, but so far I've been able to wrap my head around everything. But the OrderBy is causing me issues. And I haven't found any issues like mine yet. I have a feeling it's because I'm missing something about the $scope and how orderBy actually works.

I'm creating a list that will display writers in my region for this years NaNoWriMo. I've separated the users as Factories, and have gotten them displayed. But, I'm having issues getting them sorted. The Name and Wordcount sort without a problem. But the Calculated Average Wordcount is not sorting at all. It won't call the function I've made for it, even.

Here's my simplified layout, and the JSFiddle setup (updated).

JS:

(function () {
var app = angular.module('userList', []);

app.controller('ListController', ['$scope',

function ($scope) {
    $scope.users = userData;
    $scope.day = 30;

    $scope.avgWords = function (user) {
        return Math.floor(user.wordcount / $scope.day);
    };

    $scope.sort = "name";
    $scope.sortRev = false;

    $scope.sortChange = function (field) {
        if ($scope.sort === field) {
            $scope.sortRev = !$scope.sortRev;
            return;
        }

        $scope.sort = field;
        $scope.sortRev = false;
    };

    $scope.sortAvg = function (user) {
        alert("sorted!");
        return Math.floor(user.wordcount / $scope.day);
    };
}]);

var userData = [{
    "name": "Kris",
        "wordcount": 42382
}, {
    "name": "Tim",
        "wordcount": 60120
}, {
    "name": "Elsa",
        "wordcount": 150675
}];
})();

HTML:

<div ng-controller="ListController">
<table>
    <thead>
        <tr>
            <th ng-click="sortChange('name');">Username</th>
            <th ng-click="sortChange('wordcount');">Total Words</th>
            <th ng-click="sortChange('sortAvg');">Average WPD</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="user in users | orderBy:sort:sortRev">
            <td>{{user.name}}</td>
            <td>{{user.wordcount}}</td>
            <td>{{avgWords(user)}}</td>
        </tr>
    </tbody>
</table>

2 Answers 2

2

You can always just add the average word property to the objects in the user array on the scope. That way each column can be filtered by the appropriate property...so something like

http://jsfiddle.net/poppypoop/swer05sx/

    $scope.users = userData;
    $scope.day = 30;

      for(var i=0; i < $scope.users.length; i++){
        $scope.users[i].avgWords = Math.floor($scope.users[i].wordcount / $scope.day);
    }
Sign up to request clarification or add additional context in comments.

2 Comments

I had the same thought, but the issue with this is that users can be added dynamically. It wouldn't update new users, only users on the initial load.
It makes more sense this way. The avgWords should naturally be a property of users. Check out this fiddle as well. So right after your Xhr request just add them in.
1

When you click on the Average WPD heading, you set $scope.sort to the string "avgWords". So, orderBy uses this string to sort the users, and thus orders the users by the value of their avgWords field, which is always undefined.

If you want to sort using a custom function rather than a field, you must set $scope.sort to the function you want to sort by:

$scope.sort = $scope.avgWords;

To do that, the ng-click on the heading should be

sortChange(avgWords)

3 Comments

Ah, I missed that. That should've been set like that. Here's the updated fiddle. The issue is still the same, though. I set my click to sortChange('sorgAvg') to correspond with the function, but it's never called.
Now I see what I was doing. You're right. The issue is the difference between calling sortChange('avgWords') and sortChange(avgWords). One looks for the property, the other looks for a function. All this time, and it was caused by two ''! Thanks.
To be really accurate, the other doesn't look specifically for a function. It looks for a property of the current scope named avgWords, whatever its type is.

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.