Sorting multiple columns in Angular using the $filter and an array of predicate functions

For my Angular project, I need to order an array using the $filter('orderBy') function. Specifically, I want to specify three predicate callbacks and have the sort order be ASC, DESC, ASC.

I am well aware that there are various methods to achieve multi-column sorting in Angular, but my focus is on utilizing the orderBy filter for this task.

The examples I will provide are not actual data but rather a simplified model to aid in explanation.

One common approach is to use simple property names like so:

$scope.arr = $filter('orderBy')($scope.arr, ['+year', '-month', '+payment']);

However, my specific orderBy code setup involves functions as follows:

$scope.arr = $filter('orderBy')($scope.arr, [
      function(row) {
          //complex logic here...for demonstration purposes returning the raw property  
          return row.year;
      },
      function(row) {
          //complex logic here...for demonstration purposes returning the raw property
          return row.month;
      },
      function(row) {
          //complex logic here...for demonstration purposes returning the raw property
          return row.payment;
      }
    ], true);
  }

Despite using an array of functions for ordering, I am struggling to implement ASC, DESC, ASC sorting order. While flipping the whole array with the third argument works (

$filter('orderBy')($scope.arr,[...], true)
), it's not the solution I desire.

I attempted structuring the array differently, but it did not yield the desired outcome:

['+', function(row){return row.year;}, '-', function(row){return row.month}, '+', function(row){return row.payment;}]

I find myself at a loss. Is there a way to utilize the predicate function callbacks while achieving per-property specified direction sorting?

angular.module('app', []).controller('MyController', function($scope, $filter) {
  var id = 0;
  var arr = [];
  //generate some dummy data
  for (var year = 2000; year < 2010; year++) {

    for (var month = 3; month > 0; month--) {
      for (var payment = 100; payment < 300; payment = payment + 50) {
        var row = {
          id: id++,
          year: year,
          month: '0' + month,
          payment: payment
        };
        arr.push(row);
      }
    }
  }
  $scope.arr = arr;

  $scope.order = function() {

      $scope.arr = $filter('orderBy')($scope.arr, [
        function(row) {
          return row.year;
        },
        function(row) {
          return row.month;
        },
        function(row) {
          return row.payment;
        }
      ], true);
    }
    //sort the array right away
  $scope.order();

});
th {
      padding: 10px 20px;
      border: 1px solid black;
      background-color: lightgrey;
      text-align: center;
    }
    td {
      padding: 10px 20px;
      border: 1px solid red;
    }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="MyController">
    <table>
      <tr>
        <th>ID</th>
        <th>Year</th>
        <th>Month</th>
        <th>Payment</th>
      </tr>
      <tr ng-repeat="row in arr">
        <td>{{row.id}}</td>
        <td>{{row.year}}</td>
        <td>{{row.month}}</td>
        <td>{{row.payment}}</td>
      </tr>
    </table>
  </div>
</div>

Answer №1

Would you mind giving this a shot?

const obtainYear = (row) => {
      //complex calculations here...just presenting the raw property for now
      return row.year;
  };

const getMonth = (row) => {
      //intricate computations here...just revealing the raw property as an example
      return -1 * row.month;
  };
  
const retrievePayment = (row) => {
      //elaborate operations here...just displaying the raw property temporarily
      return row.payment;
  };

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I prevent event propagation in Vuetify's v-switch component?

Currently, I am working with Vuetify and have incorporated the use of v-data-table. Whenever I click on a row within this data table, a corresponding dialog box represented by v-dialog should open. Additionally, each row contains a v-switch element. Howeve ...

Is this example a strong demonstration of implementing simple inheritance in JavaScript?

Having transitioned from using Dojo, there's one specific thing that I deeply miss - Dojo's declare() function. Developing a rather complex application, I found myself extensively modifying Node's lang.inherits() to enhance its functionality ...

What do you understand by the term "cyclic data structures"?

According to the information found on the JSON site, it states: JSON does not allow for cyclic data structures, hence one must avoid passing cyclical structures to the JSON stringify function. I am curious about what this means. Could someone provide a ...

Steps to send a table to PHP and store it as a text file

I have this program for a form data entry. It includes text boxes to input values, and upon clicking 'Submit', the input values should be displayed below while resetting the text box for another set of inputs. The issue I am facing is with the sa ...

The redirect function is failing to carry the "req" parameter

Express Routes Troubleshooting app.get('/auth/google/redirect', passport.authenticate('google'), (req, res) => { console.log('req.user:', req.user) //>>>>>Outputs {username: 'bob', id: '.. ...

What is the best way to utilize ng-if to conceal a component in AngularJS when a button in a separate component is clicked?

I am facing a challenge with two child components within a parent component. My goal is to hide component1 when a button in component2 is clicked. Below is an illustration of the current code I am handling: Parent Component HTML: <div ng-app='ap ...

What could be causing a template value in my AngularJS/Ionic Framework code to not be replaced properly?

Recently, I've been exploring the world of Ionic Framework with Angular by my side. However, I've hit a bit of a roadblock. My goal is to set up tabs at the bottom of my application using a model definition. Here's what I've tried so ...

Tips on when to display the "Email Confirmation" input text box only after updating the old email

Oh no!! Yes, that's exactly what I desire! I've been facing obstacles in trying to understand how to display the "Email Confirm" input text-box ONLY when the old email has been updated. Can someone point out where I might have gone wrong? :( ...

I am interested in developing a JavaScript program that can calculate multiples of 0.10

I am looking to let users input values that are multiples of 0.10, such as - 0.10, 0.20, 0.30....1.00, 1.10, 1.20...1.90, and so on. When a user enters a value in the text box, I have been checking the following validation: amount % 0.10 == 0 Is this a ...

Adjust Camera Position in A-Frame Scene Based on Scrolling Movement

I've been struggling to find a solution for this particular scenario in Aframe. I want to create an embedded Aframe scene as the background of a webpage and have the camera move along a path as the user scrolls down the page. I've set up a scene ...

My Angular custom libraries are having issues with the typing paths. Can anyone help me troubleshoot what I might be doing

After successfully creating my first custom Angular library using ng-packagr, I encountered an issue where the built library contained relative paths specific to my local machine. This posed a problem as these paths would not work for anyone else trying to ...

Having trouble retrieving data from the MongoDB database using Node.js

Having trouble with data retrieval from MongoDb Successfully connected to MongoDb, but when using the find command, it should return an empty collection, yet nothing is being returned. What could be causing this issue and how can it be monitored through ...

What is the best method for incorporating success icons into my website with vue.js?

Hey everyone, please excuse my lack of expertise as I am a beginner in this field. I'm trying to incorporate success icons into my website using bootstrap or similar tools, but I'm unsure of how to implement the if statement below. If anyone co ...

Express encountered an issue when trying to upload a file through AngularJS

I am currently facing an issue with uploading a file to express and subsequently to mongoDB. Despite my efforts, when I attempt to upload the file to express, it appears that no data is being passed through the response. I am utilizing ng-file-upload.min. ...

Is there a way to track the number of visits by a 'user' to a website?

Looking to hide certain parts of my website from users who have visited more than a specified number of times. The NY Times site has something similar. Utilizing react & firebase for this project. Considered using IP addresses, but it seems to identify l ...

Electron employee: Concealed BrowserWindow leads to delay in the interface

My worker runs in a hidden browser window and sends multiple requests simultaneously. However, these requests from the worker end up causing lag and freezes in the main browser window. Any suggestions for resolving this issue? ...

Combining items in Python lists

Suppose we have a string, let's call it s='135', and a list, let's call it A=['1','2','3','4','5','6','7']. How can we extract the values from the list that are also ...

Retrieve an array of existing fields in MongoDB by comparing a collection with an array of objects

I'm a newbie when it comes to Mongo and I'm attempting to compare an array with a collection of documents, returning a list of matching records. Let me break it down:First Array I have a collection (user) with the following documents: > db. ...

Dynamic route fails to return value for ID search

Currently, I am testing by creating an array of users containing their respective IDs and names. There is also a button that triggers an onclick function to add the element's ID to the page's URL in order to establish a dynamic route. However, wh ...

How to efficiently transfer data between Node and Angular 7 using Electron

After setting up an Angular 7 application running on http://localhost:4200, I developed a Node JS application responsible for authenticating users on Facebook, accessible at http://localhost:3000. The callback redirection functions correctly within the No ...