I have a component.
@Component({
selector: 'top3',
templateUrl: 'dev/templates/top3.html',
pipes: [orderBy],
providers: [HTTP_PROVIDERS, ParticipantService]
})
export class AppTop3Component implements OnInit {
constructor (private _participantService: ParticipantService) {}
errorMessage: string;
participants: any[];
ngOnInit() {
this.getParticipants();
}
getParticipants() {
this._participantService.getParticipants()
.then(
participants => this.participants = participants,
error => this.errorMessage = <any>error
);
}
}
This component use a service, named _participantService. The _participantService retrieves an array of objects. I output my array of objects in component`s template:
<h2>Top 3</h2>
<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 | orderBy: '-score'; #i = index">
<td>{{i+1}}</td>
<td>{{participant.username}}</td>
<td>{{participant.score}}</td>
</tr>
</tbody>
</table>
I use a Pipe, named orderBy with *ngFor directive. The problem is when I don`t use a Pipe and output array in this way:
<tr *ngFor="#participant of participants; #i = index">
everything is OK, and I've got a correct result:

But when I want to sort my object's array and use my Pipe, I don't have any output:

I`ve got an undefined object in my Pipe function^
@Pipe({
name: 'orderBy',
pure: false
})
export class orderBy implements PipeTransform {
transform(arr: any[], orderFields: string[]): any {
console.log(arr);
orderFields.forEach(function(currentField: string) {
var orderType = 'ASC';
if (currentField[0] === '-') {
currentField = currentField.substring(1);
orderType = 'DESC';
}
arr.sort(function(a, b) {
return (orderType === 'ASC') ?
(a[currentField] < b[currentField]) ? -1 :
(a[currentField] === b[currentField]) ? 0 : 1 :
(a[currentField] < b[currentField]) ? 1 :
(a[currentField] === b[currentField]) ? 0 : -1;
});
});
return arr;
}
}

Since you load your data asynchronously using a promise, they are null at the beginning (before the first callback defined in the then method is called).
You need to check if the are parameter is null in your pipe. If so you shouldn't execute the "order by" processing...
When the result will be there, the pipe will be called again with the data (are won't be null). In this case, you will be able to sort data...
You could try this code:
@Pipe({
name: 'orderBy',
pure: false
})
export class orderBy implements PipeTransform {
transform(arr: any[], orderFields: string[]): any {
if (arr==null) {
return null;
}
(...)
}
}
According to an example of the doc of the Pipes (https://angular.io/docs/ts/latest/guide/pipes.html#!#jsonpipe), you missed parenthesis :
<tr *ngFor="#participant of (participants | orderBy: '-score'); #i = index">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With