I have the following code:
This is the HTML view:
<button type="button" (click)="filterIt('male')">Filter male gender</button>
<table>
<ng-container *ngFor="let item of array;let i=index">
<tr class="border-bottom" *ngIf="item.condition==condition_var">
<td>{{i+1}}</td>
<td>{{item.condition}}</td>
</tr>
</ng-container>
</table>
This is the typescript file (.ts):
condition_var:string;
filterIt(value){
this.condition_var=value;
}
NOTE: the array variable is already populated. (array of objects:
[{}])
My question is: Is it a practice in angular2 to always declare variables and to work with them in expressions, ngIf, ngFor etc. Or can I use a better way rather than populating my class with too many variables which doesn't look good.
To be more specific, is there a better way to write this code?
Yes there is a better (more idiomatic) way to do this: use a @Pipe.
import { Pipe, PipeTransform } from "@angular/core";
@Pipe({ name: 'filter' })
export class FilterPipe implements PipeTransform {
transform(values: any, condition: any): any {
return values.filter(item => item.condition === condition);
}
}
Implement with:
<ng-container *ngFor="let item of array | filter:condition">
And set the condition however you like. Note that filters can accept more than one positional parameter, separated by colons.
Remember to add the pipe to whichever @NgModules you use the pipe in:
import { FilterPipe } from 'pipes/fitler.pipe.ts';
@NgModule({
declaractions: [
FilterPipe
],
// ...
})
And if the @NgModule in question is a lazy-loaded "shared" module, don't forget to re-export it:
@NgModule({
declaractions: [
FilterPipe
],
exports: [
FilterPipe
],
// ...
})
This answer is currently valid as of angular 4.3.6.
I would use a getter inside your component class which filters the array you're looping over. Like this:
public myArray: any[] = [];
public myCondition: string | null = null;
public get myFilteredArray() {
return this.myArray.filter(item => item.condition === this.myCondition);
}
And in your template just use the filteredArray:
<table>
<tr class="border-bottom" *ngFor="let item of myFilteredArray;let i=index">
<td>{{i+1}}</td>
<td>{{item.condition}}</td>
</tr>
</table>
Or you could build a pipe for it:
@Pipe({ name: 'myFilterPipe' })
export class MyFilterPipe implements PipeTransform {
transform(value: any[], condition: string | null): any[] {
if(!Array.isArray(value)) return [];
return value.filter(item => item.condition === condition);
}
}
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