I'm trying to create a custom Pipe in Angular 2 that will sort an array of objects. I garnered a bit of help from this post. However, I can't seem to get this working.
My pipe looks like this:
@Pipe({
name: "orderByAsync",
pure: false
})
export class AsyncArrayOrderByPipe {
private _promise : Promise<Array<Object>>;
private _output: Array<Object>;
transform(promise: Promise<Array<Object>>, args: any): Array<Object>{
var _property : string = "";
var _descending : boolean = false;
this._property = args[0]["property"] || "";
this._descending = args[0]["descending"] || false;
if(!this._promise) {
this._promise = promise.then((result) => {
result.sort((a: any, b: any) => {
if (a[this._property] < b[this._property]) return (this._descending ? 1: -1);
else if (a[this._property] > b[this._property]) return (this._descending ? -1: 1);
else return 0;
});
this._output = result;
});
}
return this._output;
}
}
The use of the pipe would look like this:
<div *ngFor="#c of countries | orderByAsync">{{c.name}}</div>
It's like the view is never notified that the promise has resolved and data has been returned.
What am I missing?
The built in
async
pipe injects aChangeDetectorRef
and callsmarkForCheck()
on it when the promise resolves. To do it all in one pipe, you should follow that example. You can view the Typescript source for that here.I would suggest, however, forgetting about handling async on your own and instead write a pure stateless sorting pipe and chain it with the built in
async
pipe. For that, you would write your pipe to handle a bareArray
, not a promise, and use it like this:Simply return a BehaviorSubject out of your pipe which then can get bound with angular async pipe.
Small example (put it in your transform method of your pipe) which should give you 'value' after 3 seconds:
Complete example: