Reputation: 11
I want to filter my columns of my table based on text entered by user. I am using the following pipe,
import {Pipe, PipeTransform} from 'angular2/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/filter';
@Pipe({
name: "search"
})
export class SearchPipe implements PipeTransform {
searchTerms: Map<string, string> = new Map<string, string>();
key: string;
term: string = "*";
transform(input, [colIndex, term, key]) {
console.log("start of search " + term + " key:" + key);
this.key = key;
this.term = term;
if (this.term == '*') {
return input;
} else {
input.filter(
function(data) {
data.forEach(
e=> {
console.log("filtering data " + e[key]+" result is : "+e[key].contains(term));
return e[key].contains(term);
}
)
}
).subscribe(
function(err) {
console.log('Error: %s', err);
},
function() {
console.log('Completed');
}
)
}
}
}
In my html page,
<tr *ngFor="#column of (tableData.columns | search:columnIndex:filterTerm:columnKey | async )" (click)="onRowSelect(column)">
<td *ngFor="#key of column | jsonIterator">{{column[key]}}</td>
</tr>
tableData.columns is of type Observable which i am getting from a json file which is having contents as ,
[{"Component ID":"1","Component Type":"abc","Label Value":"user ID","Tool Tip Value":"please enter user ID"},
{"Component ID":"2","Component Type":"oit","Label Value":"user name","Tool Tip Value":"please enter user name"}
]
'term' is the entered text which will be searched against the value of 'key' in the json. JsonIterator is my another pipe from where i get my keys in my json
As the user enters the text, my data table gets cleaned up. What am I missing?
and also is my approach correct? As I am new to angular js 2 i am unaware of the conventions followed while implementing such components. I mean is this correct way to user filter an observable or should i use map or something else ?
the column data is populated as,
this.tableBean.columns = this.http.get('appLiteral.json')
.map(res => res.json());
Upvotes: 1
Views: 2262
Reputation: 202326
I would revert the order you apply filter in your ngFor. I would put the async pipe right after the observable:
<tr *ngFor="#column of (tableData.columns | async |search:columnIndex:filterTerm:columnKey)" (click)="onRowSelect(column)">
And remove from your custom pipe the use of the observable api.
In fact, when the data will ne received from the observable, the pipe will be called again with these data. You will be able to filter them in your custom pipe.
The problem of your code is that you define nothing in the subscribe method within your custom pipe. So your pipe returns nothing (no data)...
If you really want to leverage an observable within your custom pipe, you could have a look at this link:
https://github.com/angular/angular/blob/master/modules/angular2/src/common/pipes/async_pipe.ts
Upvotes: 0