How to use custom pipe on async pipe?

Shree picture Shree · Jan 9, 2017 · Viewed 13.5k times · Source

I'm trying to create custom pipe on asynchronous pipe, I tried many solutions, but still not working. Here is the snippet of code.

product.sort.ts - custom pipe

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

@Pipe({
    name: 'sortByName'
})
export class ProductPipe implements PipeTransform{
    /*transform(values: Array<any>, term:string){
        return values.filter(obj => obj.pname.startsWith(term))
    }*/

    //CODE NOT WORKING >>>>>
    transform($value: Observable<Array<any>>, term:string){
        if($value){
            $value.subscribe(
                (obj) => {
                    return obj.filter(obj => obj.pname.startsWith(term))
                }
            )
        }
    }
}

products.component.ts - main component

import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { AppService } from '../app.service/app.service';
import { ProductPipe } from '../products.sort/products.sort';

@Component({
    selector: 'products-pg',
    template: `
        Products List:
        <ul>
            <li *ngFor = 'let product of $productList | async | sortByName:"A"'>{{product.pname}}</li>
        </ul>
    `
})
export class ProductsComponent implements OnInit{
    private $productList:Observable<Array<any>>;

    constructor(private _service: AppService, private _store: Store<Array<any>>){}

    ngOnInit(){
        this._service.setProductList();
        this.$productList = this._store.select('products');
    }
}

Here, I'm using store for state management, I'm trying to sort by name, so passing "A" as first letter. Since $productList is observable, how to write pipe which handles asynchronous behavior like this, plase help me to solve this.

Answer

Aran Dekar picture Aran Dekar · Mar 8, 2017

I had the same issue as well the way I fixed it, was like this:

<li class="list-group-item" *ngFor='let alert of _alerts$ | ipwrAlertFilter:seeAll | async'>

look how I had my custom filter before the async pipe, this way my custom pipe gets an observable and then in my pipe I have this:

return value.map(data => data.filter(x => x.originalHasBeenSeen === false));

this way my custom pipe still returns something that I can still apply async pipe on. and so with each new item in stream I still get a hit on my custom pipe and my view gets updated. hope this helps.