OrderBy pipe issue

user4956851 picture user4956851 · Feb 2, 2016 · Viewed 240.1k times · Source

I'm not able to translate this code from Angualr 1 to Angular 2:

ng-repeat="todo in todos | orderBy: 'completed'"

This is what i've done following the Thierry Templier's answer:

Component template:

*ngFor="#todo of todos | sort"

Component code:

@Component({
    selector: 'my-app',
    templateUrl: "./app/todo-list.component.html",
    providers: [TodoService],
    pipes: [ TodosSortPipe ]

})

Pipe code:

import { Pipe } from "angular2/core";
import {Todo} from './todo';

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

I'm trying to sort an array of Todos, ordered by the property completed. First todo.completed = false and then the todo.complete = true.

I don't understand very well the transform method and how to pass the arguments in that method and in the sort method.

What is the args: string argument? What are a and b and where they come from?

Answer

Sal picture Sal · Jun 13, 2017

I modified @Thierry Templier's response so the pipe can sort custom objects in angular 4:

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

@Pipe({
  name: "sort"
})
export class ArraySortPipe  implements PipeTransform {
  transform(array: any, field: string): any[] {
    if (!Array.isArray(array)) {
      return;
    }
    array.sort((a: any, b: any) => {
      if (a[field] < b[field]) {
        return -1;
      } else if (a[field] > b[field]) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

And to use it:

*ngFor="let myObj of myArr | sort:'fieldName'"

Hopefully this helps someone.