AngularJS: Order by sum of grouped list











up vote
0
down vote

favorite












I have a list of single match outcomes of different teams in the following form:



    [{team: "A", w: 1, l: 0, t: 0, date: '2018-10-01'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-01'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-01'},
{team: "D", w: 0, l: 1, t: 0, date: '2018-10-01'},
{team: "A", w: 1, l: 0, t: 0, date: '2018-10-08'},
{team: "B", w: 0, l: 1, t: 0, date: '2018-10-08'},
{team: "C", w: 0, l: 0, t: 1, date: '2018-10-08'},
{team: "D", w: 0, l: 0, t: 1, date: '2018-10-08'},
{team: "A", w: 1, l: 0, t: 0, date: '2018-10-15'},
{team: "D", w: 0, l: 0, t: 0, date: '2018-10-15'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-15'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-17'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-20'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-20'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-22'}]


Using ng-repeat and angular.filter I am now able to display that data in a table grouped by team. Using this suggestion I am also able to aggregate the game outcomes to produce a record for each team:



Rank    Team    Games   Wins    Losses  Ties
1 A 3 3 0 0
2 D 3 0 1 1
3 C 4 0 3 1
4 B 5 4 1 0


Here is a jsfiddle of what I got so far.



Additionally I have a datepicker placed in the view from which the user will be able to select date ranges. Upon changing these dates the aggregates are updated. This is also already working.



My problem now is that I am unable to order my table by any of the displayed categories. I tried different things like using any kind of orderBy: clause imaginable. I also tried putting the result of my aggregation in a variable (like {{ wins = reduce(group, 'w') }}) to be referenced in the orderBy:, but to no avail.



Is it at all possible what I'd like to achieve?










share|improve this question
























  • There's a number of outdated practices here that I feel make it more difficult for you. You should be initiating the data within the controller so you don't have to rely on the piped directives, and then sorting by clicking a column header is just as easy: simply sort the array by the wins, or losses, or what have you.
    – Devin Fields
    Nov 15 at 0:20










  • Agree. Map/reduce the data first before sending to view
    – charlietfl
    Nov 15 at 0:29












  • Thanks for your comment. This is a scaled down version of what I‘m actually doing, maybe that’s a reason why it seems a little awkward. What do you mean by initiating the data within the controller?
    – le_affan
    Nov 15 at 0:30






  • 1




    I updated the fiddle to show you. It's not complete, but basically all you need to do is calculate the ranks and put that on it's own property, maybe 'r' jsfiddle.net/g4b5tcqp/1
    – Devin Fields
    Nov 15 at 0:41










  • Thanks again, I'll have a look at it.
    – le_affan
    Nov 15 at 0:44















up vote
0
down vote

favorite












I have a list of single match outcomes of different teams in the following form:



    [{team: "A", w: 1, l: 0, t: 0, date: '2018-10-01'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-01'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-01'},
{team: "D", w: 0, l: 1, t: 0, date: '2018-10-01'},
{team: "A", w: 1, l: 0, t: 0, date: '2018-10-08'},
{team: "B", w: 0, l: 1, t: 0, date: '2018-10-08'},
{team: "C", w: 0, l: 0, t: 1, date: '2018-10-08'},
{team: "D", w: 0, l: 0, t: 1, date: '2018-10-08'},
{team: "A", w: 1, l: 0, t: 0, date: '2018-10-15'},
{team: "D", w: 0, l: 0, t: 0, date: '2018-10-15'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-15'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-17'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-20'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-20'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-22'}]


Using ng-repeat and angular.filter I am now able to display that data in a table grouped by team. Using this suggestion I am also able to aggregate the game outcomes to produce a record for each team:



Rank    Team    Games   Wins    Losses  Ties
1 A 3 3 0 0
2 D 3 0 1 1
3 C 4 0 3 1
4 B 5 4 1 0


Here is a jsfiddle of what I got so far.



Additionally I have a datepicker placed in the view from which the user will be able to select date ranges. Upon changing these dates the aggregates are updated. This is also already working.



My problem now is that I am unable to order my table by any of the displayed categories. I tried different things like using any kind of orderBy: clause imaginable. I also tried putting the result of my aggregation in a variable (like {{ wins = reduce(group, 'w') }}) to be referenced in the orderBy:, but to no avail.



Is it at all possible what I'd like to achieve?










share|improve this question
























  • There's a number of outdated practices here that I feel make it more difficult for you. You should be initiating the data within the controller so you don't have to rely on the piped directives, and then sorting by clicking a column header is just as easy: simply sort the array by the wins, or losses, or what have you.
    – Devin Fields
    Nov 15 at 0:20










  • Agree. Map/reduce the data first before sending to view
    – charlietfl
    Nov 15 at 0:29












  • Thanks for your comment. This is a scaled down version of what I‘m actually doing, maybe that’s a reason why it seems a little awkward. What do you mean by initiating the data within the controller?
    – le_affan
    Nov 15 at 0:30






  • 1




    I updated the fiddle to show you. It's not complete, but basically all you need to do is calculate the ranks and put that on it's own property, maybe 'r' jsfiddle.net/g4b5tcqp/1
    – Devin Fields
    Nov 15 at 0:41










  • Thanks again, I'll have a look at it.
    – le_affan
    Nov 15 at 0:44













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have a list of single match outcomes of different teams in the following form:



    [{team: "A", w: 1, l: 0, t: 0, date: '2018-10-01'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-01'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-01'},
{team: "D", w: 0, l: 1, t: 0, date: '2018-10-01'},
{team: "A", w: 1, l: 0, t: 0, date: '2018-10-08'},
{team: "B", w: 0, l: 1, t: 0, date: '2018-10-08'},
{team: "C", w: 0, l: 0, t: 1, date: '2018-10-08'},
{team: "D", w: 0, l: 0, t: 1, date: '2018-10-08'},
{team: "A", w: 1, l: 0, t: 0, date: '2018-10-15'},
{team: "D", w: 0, l: 0, t: 0, date: '2018-10-15'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-15'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-17'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-20'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-20'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-22'}]


Using ng-repeat and angular.filter I am now able to display that data in a table grouped by team. Using this suggestion I am also able to aggregate the game outcomes to produce a record for each team:



Rank    Team    Games   Wins    Losses  Ties
1 A 3 3 0 0
2 D 3 0 1 1
3 C 4 0 3 1
4 B 5 4 1 0


Here is a jsfiddle of what I got so far.



Additionally I have a datepicker placed in the view from which the user will be able to select date ranges. Upon changing these dates the aggregates are updated. This is also already working.



My problem now is that I am unable to order my table by any of the displayed categories. I tried different things like using any kind of orderBy: clause imaginable. I also tried putting the result of my aggregation in a variable (like {{ wins = reduce(group, 'w') }}) to be referenced in the orderBy:, but to no avail.



Is it at all possible what I'd like to achieve?










share|improve this question















I have a list of single match outcomes of different teams in the following form:



    [{team: "A", w: 1, l: 0, t: 0, date: '2018-10-01'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-01'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-01'},
{team: "D", w: 0, l: 1, t: 0, date: '2018-10-01'},
{team: "A", w: 1, l: 0, t: 0, date: '2018-10-08'},
{team: "B", w: 0, l: 1, t: 0, date: '2018-10-08'},
{team: "C", w: 0, l: 0, t: 1, date: '2018-10-08'},
{team: "D", w: 0, l: 0, t: 1, date: '2018-10-08'},
{team: "A", w: 1, l: 0, t: 0, date: '2018-10-15'},
{team: "D", w: 0, l: 0, t: 0, date: '2018-10-15'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-15'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-17'},
{team: "B", w: 1, l: 0, t: 0, date: '2018-10-20'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-20'},
{team: "C", w: 0, l: 1, t: 0, date: '2018-10-22'}]


Using ng-repeat and angular.filter I am now able to display that data in a table grouped by team. Using this suggestion I am also able to aggregate the game outcomes to produce a record for each team:



Rank    Team    Games   Wins    Losses  Ties
1 A 3 3 0 0
2 D 3 0 1 1
3 C 4 0 3 1
4 B 5 4 1 0


Here is a jsfiddle of what I got so far.



Additionally I have a datepicker placed in the view from which the user will be able to select date ranges. Upon changing these dates the aggregates are updated. This is also already working.



My problem now is that I am unable to order my table by any of the displayed categories. I tried different things like using any kind of orderBy: clause imaginable. I also tried putting the result of my aggregation in a variable (like {{ wins = reduce(group, 'w') }}) to be referenced in the orderBy:, but to no avail.



Is it at all possible what I'd like to achieve?







javascript angularjs angular-filters






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 at 0:43

























asked Nov 15 at 0:14









le_affan

3168




3168












  • There's a number of outdated practices here that I feel make it more difficult for you. You should be initiating the data within the controller so you don't have to rely on the piped directives, and then sorting by clicking a column header is just as easy: simply sort the array by the wins, or losses, or what have you.
    – Devin Fields
    Nov 15 at 0:20










  • Agree. Map/reduce the data first before sending to view
    – charlietfl
    Nov 15 at 0:29












  • Thanks for your comment. This is a scaled down version of what I‘m actually doing, maybe that’s a reason why it seems a little awkward. What do you mean by initiating the data within the controller?
    – le_affan
    Nov 15 at 0:30






  • 1




    I updated the fiddle to show you. It's not complete, but basically all you need to do is calculate the ranks and put that on it's own property, maybe 'r' jsfiddle.net/g4b5tcqp/1
    – Devin Fields
    Nov 15 at 0:41










  • Thanks again, I'll have a look at it.
    – le_affan
    Nov 15 at 0:44


















  • There's a number of outdated practices here that I feel make it more difficult for you. You should be initiating the data within the controller so you don't have to rely on the piped directives, and then sorting by clicking a column header is just as easy: simply sort the array by the wins, or losses, or what have you.
    – Devin Fields
    Nov 15 at 0:20










  • Agree. Map/reduce the data first before sending to view
    – charlietfl
    Nov 15 at 0:29












  • Thanks for your comment. This is a scaled down version of what I‘m actually doing, maybe that’s a reason why it seems a little awkward. What do you mean by initiating the data within the controller?
    – le_affan
    Nov 15 at 0:30






  • 1




    I updated the fiddle to show you. It's not complete, but basically all you need to do is calculate the ranks and put that on it's own property, maybe 'r' jsfiddle.net/g4b5tcqp/1
    – Devin Fields
    Nov 15 at 0:41










  • Thanks again, I'll have a look at it.
    – le_affan
    Nov 15 at 0:44
















There's a number of outdated practices here that I feel make it more difficult for you. You should be initiating the data within the controller so you don't have to rely on the piped directives, and then sorting by clicking a column header is just as easy: simply sort the array by the wins, or losses, or what have you.
– Devin Fields
Nov 15 at 0:20




There's a number of outdated practices here that I feel make it more difficult for you. You should be initiating the data within the controller so you don't have to rely on the piped directives, and then sorting by clicking a column header is just as easy: simply sort the array by the wins, or losses, or what have you.
– Devin Fields
Nov 15 at 0:20












Agree. Map/reduce the data first before sending to view
– charlietfl
Nov 15 at 0:29






Agree. Map/reduce the data first before sending to view
– charlietfl
Nov 15 at 0:29














Thanks for your comment. This is a scaled down version of what I‘m actually doing, maybe that’s a reason why it seems a little awkward. What do you mean by initiating the data within the controller?
– le_affan
Nov 15 at 0:30




Thanks for your comment. This is a scaled down version of what I‘m actually doing, maybe that’s a reason why it seems a little awkward. What do you mean by initiating the data within the controller?
– le_affan
Nov 15 at 0:30




1




1




I updated the fiddle to show you. It's not complete, but basically all you need to do is calculate the ranks and put that on it's own property, maybe 'r' jsfiddle.net/g4b5tcqp/1
– Devin Fields
Nov 15 at 0:41




I updated the fiddle to show you. It's not complete, but basically all you need to do is calculate the ranks and put that on it's own property, maybe 'r' jsfiddle.net/g4b5tcqp/1
– Devin Fields
Nov 15 at 0:41












Thanks again, I'll have a look at it.
– le_affan
Nov 15 at 0:44




Thanks again, I'll have a look at it.
– le_affan
Nov 15 at 0:44












1 Answer
1






active

oldest

votes

















up vote
1
down vote













One solution is to take advantage of the fact you can pass a function as the expression argument into orderBy. Inside this function you can compute the summation of all items in a group for each property, then use the result as the value to order by.



The adjustment to your HTML:



ng-repeat="group in data | groupBy: 'team' | toArray:true | orderBy:category"


And the relevant JS to make it happen:



// $scope.order is a user option to specify the property to order by
$scope.category = function (value) {
// The games column is not a data item property so it is treated specially
if ($scope.order === 'games') {
return value.length;
}
return value.reduce(function (total, dataItem) {
return total + dataItem[$scope.order];
}, 0);
};


And here's forked JSFiddle demonstrating the suggestion.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310678%2fangularjs-order-by-sum-of-grouped-list%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote













    One solution is to take advantage of the fact you can pass a function as the expression argument into orderBy. Inside this function you can compute the summation of all items in a group for each property, then use the result as the value to order by.



    The adjustment to your HTML:



    ng-repeat="group in data | groupBy: 'team' | toArray:true | orderBy:category"


    And the relevant JS to make it happen:



    // $scope.order is a user option to specify the property to order by
    $scope.category = function (value) {
    // The games column is not a data item property so it is treated specially
    if ($scope.order === 'games') {
    return value.length;
    }
    return value.reduce(function (total, dataItem) {
    return total + dataItem[$scope.order];
    }, 0);
    };


    And here's forked JSFiddle demonstrating the suggestion.






    share|improve this answer



























      up vote
      1
      down vote













      One solution is to take advantage of the fact you can pass a function as the expression argument into orderBy. Inside this function you can compute the summation of all items in a group for each property, then use the result as the value to order by.



      The adjustment to your HTML:



      ng-repeat="group in data | groupBy: 'team' | toArray:true | orderBy:category"


      And the relevant JS to make it happen:



      // $scope.order is a user option to specify the property to order by
      $scope.category = function (value) {
      // The games column is not a data item property so it is treated specially
      if ($scope.order === 'games') {
      return value.length;
      }
      return value.reduce(function (total, dataItem) {
      return total + dataItem[$scope.order];
      }, 0);
      };


      And here's forked JSFiddle demonstrating the suggestion.






      share|improve this answer

























        up vote
        1
        down vote










        up vote
        1
        down vote









        One solution is to take advantage of the fact you can pass a function as the expression argument into orderBy. Inside this function you can compute the summation of all items in a group for each property, then use the result as the value to order by.



        The adjustment to your HTML:



        ng-repeat="group in data | groupBy: 'team' | toArray:true | orderBy:category"


        And the relevant JS to make it happen:



        // $scope.order is a user option to specify the property to order by
        $scope.category = function (value) {
        // The games column is not a data item property so it is treated specially
        if ($scope.order === 'games') {
        return value.length;
        }
        return value.reduce(function (total, dataItem) {
        return total + dataItem[$scope.order];
        }, 0);
        };


        And here's forked JSFiddle demonstrating the suggestion.






        share|improve this answer














        One solution is to take advantage of the fact you can pass a function as the expression argument into orderBy. Inside this function you can compute the summation of all items in a group for each property, then use the result as the value to order by.



        The adjustment to your HTML:



        ng-repeat="group in data | groupBy: 'team' | toArray:true | orderBy:category"


        And the relevant JS to make it happen:



        // $scope.order is a user option to specify the property to order by
        $scope.category = function (value) {
        // The games column is not a data item property so it is treated specially
        if ($scope.order === 'games') {
        return value.length;
        }
        return value.reduce(function (total, dataItem) {
        return total + dataItem[$scope.order];
        }, 0);
        };


        And here's forked JSFiddle demonstrating the suggestion.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 15 at 2:04

























        answered Nov 15 at 1:58









        miqh

        2,57021729




        2,57021729






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53310678%2fangularjs-order-by-sum-of-grouped-list%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How to change which sound is reproduced for terminal bell?

            Can I use Tabulator js library in my java Spring + Thymeleaf project?

            Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents