Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2. How to apply orderBy?

I have a piece of code.

<table class="table table-bordered table-condensed" cellpadding="0" cellspacing="0">
    <thead>
        <tr>
            <th>#</th>
            <th>Name</th>
            <th>Score</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="#participant of participants; #i = index">
            <td>{{i+1}}</td>
            <td>{{participant.username}}</td>
            <td>{{participant.score}}</td>
        </tr>
    </tbody>
</table>

In Angular 1 i have orderBy filter to order rows by my filter. But how can i do orderBy in Angular 2 the same way ? Thank you.

like image 961
Edward Avatar asked Feb 17 '16 15:02

Edward


3 Answers

If you are using lodash your pipe can be like this:

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

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

And then you can use all the power of the method:

<li *ngFor="let product of products | orderBy: 'price': 'desc'">
  {{product.name}}
</li>
like image 121
Alex Chuev Avatar answered Oct 18 '22 11:10

Alex Chuev


You need to implement a custom pipe for this. This corresponds to create a class decorated by @Pipe. Here is a sample. Its transform method will actually handle the list and you will be able to sort it as you want:

import { Pipe } from "angular2/core";

@Pipe({
  name: "orderby"
})
export class OrderByPipe {
  transform(array: Array<string>, args: string): Array<string> {
    array.sort((a: any, b: any) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

You can then use this pipe as described below in expressions. For example in an ngFor. Don't forget to specify your pipe into the pipes attribute of the component where you use it:

@Component({
  (...)
  template: `
    <li *ngFor="list | orderby"> (...) </li>
  `,
  pipes: [ OrderByPipe ]
})
(...)
like image 20
Thierry Templier Avatar answered Oct 18 '22 11:10

Thierry Templier


Thank you for your answers. I have written workable code below:

@Pipe({name: 'orderBy'})

export class orderBy implements PipeTransform {
    transform(obj: any, orderFields: string): any {
        orderFields.forEach(function(currentField) {
            var orderType = 'ASC';

            if (currentField[0] === '-') {
                currentField = currentField.substring(1);
                orderType = 'DESC';
            }

            obj.sort(function(a, b) {
                if (orderType === 'ASC') {
                    if (a[currentField] < b[currentField]) return -1;
                    if (a[currentField] > b[currentField]) return 1;
                    return 0;
                } else {
                    if (a[currentField] < b[currentField]) return 1;
                    if (a[currentField] > b[currentField]) return -1;
                    return 0;
                }
            });

        });
        return obj;
    }
}

This code consider order direction DESC or ASC. The usage:

<tr *ngFor="#participant of participants | orderBy: '-score'; #i = index">
like image 4
Edward Avatar answered Oct 18 '22 12:10

Edward