0

According to this question -> Ascending and Descending Sort in Angular 4

I've made the same pipe, but it can't sort numbers naturally. I mean 2 is > then 11.

How can this pipe be modified to sort both string and numbers?

@Pipe({
    name: 'orderBy'
})

export class OrderByPipe implements PipeTransform {

    transform(records: Array<any>, args?: any): any {
        if (records && records.length > 0) {
            return records.sort(function (a, b) {                 
                if (a[args.property] < b[args.property]) {
                    return -1 * args.direction;
                } else if (a[args.property] > b[args.property]) {
                    return 1 * args.direction;
                } else {
                    return 0;
                }
            });

        }
    }
}
2
  • Can you give examples, what your input and args looks like and what output you expect? Commented Jun 21, 2018 at 13:05
  • Hi, actually its exactly same as from link. Inputs are values from html table column. Commented Jun 21, 2018 at 13:12

2 Answers 2

1

This is my solution for ordering in Angular with pipe.

+Extra feature: Ascending and Descending with the third parameter.

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {

  transform(value: any[], key: string, dir: number = 1): any {
    if (!value || !key) {
      return value;
    }

    value.sort( (a, b) => {
      return ('' + a[key]).localeCompare( ('' + b[key]) ) * dir;
    });

    return value;
  }

}

I always cast values to a string, because the comparing is easiest.

Sign up to request clarification or add additional context in comments.

Comments

0

That's because you are sorting the values as strings - lexicographically. The input for your pipe seems to be of type Array<{ [propertyName: string]: [value: string] }>.

Either make sure that the input property values are numbers or convert the values to number before comparing.

In case you need to sort based on the type of the data that came to your pipe, you can use something like this:

@Pipe({
  name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {

  transform(records: Array<any>, args?: any): any {
    if (records && records.length > 0) {
      return records.sort(
        (a, b) => args.direction * (
          typeof a[args.property] === 'number'
            ? (a[args.property] - b[args.property])
            : a[args.property] > b[args.property] ? 1 : -1)
      );
    }
  }
}

Hope this helps a little :-)

Comments

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.