Reputation: 1024
I am learning angular 2 pipes and running into problem. I have an auto complete box that once input selected should filter out the data from my *ngFor that displays a list of cards. Right now when you start typing the autocomplete works but when the actual category is selected the list of cards in the ngFor does not filter. What am I missing?
Thanks
So here is my auto complete :
<form class="example-form">
<md-form-field class="example-full-width">
<input type="text" placeholder="Select a sport" aria-label="Number" mdInput
[formControl]="myControl" [mdAutocomplete]="auto">
<md-autocomplete #auto="mdAutocomplete">
<md-option *ngFor="let option of filteredOptions | matchesSport:option |
async" [value]="option">
{{ option }}
</md-option>
</md-autocomplete>
</md-form-field>
</form>
Here is my *ngFor displaying a list of md-cards:
<md-list>
<md-list-item *ngFor="let g of games; let i = index | matchesSport:option" (click)="onSelect(g)" [class.active]="i == selectedRow">
<md-card tabindex="-1">
<md-card-content>
<p md-line> {{g.Sport}}<span><i class="material-icons">accessibility</i></span> </p>
</md-card-content>
<md-card-actions>
<button md-button md-raised-button>LIKE</button>
<button md-button md-raised-button>SHARE</button>
</md-card-actions>
</md-card>
</md-list-item>
</md-list>
And here is my pipe
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name:'matchesSport'
})
export class MatchesSportPipe implements PipeTransform {
transform(items: any, category: string): Array<any> {
return items.filter(item => item.Sport === category);
}
}
And here is my controller :
import { Component, OnInit } from '@angular/core';
import { Game } from './models/game.model';
import { GameService } from './services/game-service';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/operator/map';
export class AppComponent implements OnInit {
title = 'app';
games: any[] = [ ];
statusMessage: string = "Loading games...";
selectedRow: Object;
setClickedRow: Function;
selectedGame: Game;
myControl: FormControl = new FormControl();
options = [
'Football',
'Basketball',
'Baseball',
'Lacrosse',
'Volleyball'
];
filteredOptions: Observable<string[]>;
constructor(private _gameService: GameService) {
this.filteredOptions = this.myControl.valueChanges
.startWith(null)
.map(val => val ? this.filter(val) : this.options.slice());
}
filter(val: string): string[] {
return this.options.filter(option =>
option.toLowerCase().indexOf(val.toLowerCase()) === 0);
}
onSelect(game: Game): void {
this.selectedGame = game;
}
ngOnInit() {
return this._gameService.getGames()
.subscribe((gameData) => this.games = gameData,
(error) => {
this.statusMessage = " something broke"
});
}
}
Upvotes: 0
Views: 3137
Reputation: 7326
First, Index should be after the pipe:
<md-list-item *ngFor="let g of games | matchesSport:option; let i = index ">
...
</md-list-item>
And,
you use option
which is undefined in the pipe. You need to get the value choosed from the autocomplete and put this the pipe argument (here option
):
You can use: optionSelected event in mat-autocomplete
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="optionSelected($event)" name="myname">
<mat-option *ngFor="let option of options" [value]="option">
...
</mat-option>
</mat-autocomplete>
and in component:
option: string; // <-- use it now
// ...
optionSelected(e) {
this.option = e.option.value;
}
Then, for the error:
error of : ERROR TypeError: Cannot read property 'filter' of undefined at MatchesSportPipe.webpackJsonp.../../../../../src/app/customPipe.ts.MatchesSportPipe.transform (customPipe.ts:9)
You now need to check in your pipe if items are undefined, if category is undefined, before filtering items.
export class MatchesSportPipe implements PipeTransform {
transform(items: any[], category: string): Array<any> {
if (!items) return [];
if (!category) return items;
return items.filter(item => item.Sport === category);
}
The whole behaviour resumed in a working plunker: https://embed.plnkr.co/4NDIy84YFW7OZkVPJZo5/
Upvotes: 1