20

I am looking into how to filter an array of data in Angular2.

I looked into using a custom pipe, but I feel this is not what I am looking for, as it seems more geared towards simple presentation transformations rather then filtering large sets of data.

The array is set out as follows:

getLogs(): Array<Logs> {
        return [
            { id: '1', plate: 'plate1', time: 20 },
            { id: '1', plate: 'plate2', time: 30 },
            { id: '1', plate: 'plate3', time: 30 },
            { id: '2', plate: 'plate4', time: 30 },
            { id: '2', plate: 'plate5', time: 30 },
            { id: '2', plate: 'plate6', time: 30 }
        ];
    }

I want to filter this by id. So when I enter "1" into a search bar, it updates to display the corresponding values.

If there is a method on how to do this, I would love to know!

2 Answers 2

36

There is no way to do that using a default pipe. Here is the list of supported pipes by default: https://github.com/angular/angular/blob/master/modules/angular2/src/common/pipes/common_pipes.ts.

That said you can easily add a pipe for such use case:

import {Injectable, Pipe} from 'angular2/core';

@Pipe({
    name: 'myfilter'
})
@Injectable()
export class MyFilterPipe implements PipeTransform {
    transform(items: any[], args: any[]): any {
        return items.filter(item => item.id.indexOf(args[0]) !== -1);
    }
}

And use it:

import { MyFilterPipe } from './filter-pipe';
(...)

@Component({
  selector: 'my-component',
  pipes: [ MyFilterPipe ],
  template: `
    <ul>
      <li *ngFor="#element of (elements | myfilter:'123')">(...)</li>
    </ul>
  `
})

Hope it helps you, Thierry

Sign up to request clarification or add additional context in comments.

8 Comments

what does the implementation of PipeTransform do? Im a little confused as to its purpose.
In fact, when you want to implement a pipe, you need to implement this interface and put your processing in the transform method. See the corresponding documentation for more details: angular.io/docs/ts/latest/api/core/PipeTransform-interface.html. Its first parameter correspond to the list itself and the second one to element(s) to use to filter your list...
Thanks for the explanation. Last question is it possible to make the output from *ngFor="#element of (elements | myfilter:'123') a variable?
Yes, it's possible ;-) The only thing to be careful is that the elements list is there if it's loaded using HTTP for example...
I have been hunting for a method to do this without much luck. Can you point me in the right direction? Would really appreciate it
|
5

I have a similar scenario in one of my samples

<input "(keyup)="navigate($event)" />

<div *ngFor="#row of visibleRows"></div>    

......

navigate($event){
        this.model.navigate($event.keyCode);
        this.visibleRows = this.getVisibleRows();
}

getVisibleRows(){
    return this.model.rows.filter((row) => row.rowIndex >= this.model.start && row.rowIndex < this.model.end);
}

My approach is to recalculate the array on some qualifying event. In my case it's keyup. It may seem convenient to bind to a function or filter, but it's recommended to bind to the array directly instead. This is because the change tracking will get confused since the function/filter will return a new array instance every time change tracking is triggered - regardless of what triggered it.

Here is the full source: https://github.com/thelgevold/angular-2-samples/tree/master/components/spreadsheet

I also have a demo: http://www.syntaxsuccess.com/angular-2-samples/#/demo/spreadsheet

3 Comments

Ive actually found your github very helpful already so thank you! My table in what im working on is based quite heavily on your grid using: <grid [rows] = "log" [columns] ="columns"></grid> to build the array into a table. its been a massive help in a new and sparsely documented language. This doesn't really have much relevance to the question but more a personal thanks.
Thanks! I am glad you find the samples helpful
"the change tracking will get confused since the function/filter will return a new array instance every time change tracking is triggered" -- very true, but you could return the same array instance each time if you use a stateful pipe. Or, if your component allows it, you could use the onPush change detection strategy in conjunction with a stateful pipe. I discuss both options in this SO answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.