2
votes

I have followed the Angular 2 tour of Heroes tutorial, and I am currently at this stage:

https://angular.io/docs/ts/latest/tutorial/toh-pt6.html

I can search in the search bar, and a list of hero name suggestions come up

Plunker: https://angular.io/resources/live-examples/toh-6/ts/eplnkr.html

However, what I want, is a filter bar, where I search, and the hero block automatically gets filtered depending on what is in the filter bar.

For example, in the link I provided, if I type in "Bo" in the search bar, I only want the hero block "Bombasto" to show up on the screen. When I clear the search bar, all the blocks should reappear. Does someone know how to do this?

1
Maybe you could create a minimal plunker?slaesh
Theres a plunker in the link I provided (towards the bottom).Seeker
I should really have added it to the post. Here you go angular.io/resources/live-examples/toh-6/ts/eplnkr.htmlSeeker
this might help you: stackoverflow.com/a/34165371/5115768 basically you create a custom pipe which filters your heroes array based on the search string (in the answer called filterargs)lenny
So you want the hero's displayed in the dashboard component to change based on what's in the search box?Peza

1 Answers

3
votes

Take a look at my modified plunker: https://plnkr.co/edit/YHzyzm6ZXt4ESr76mNuB?p=preview

  1. Added a Pipe to the dashboard.component.ts
@Pipe({
  name: 'filterHeros'
})
export class FilterHeroPipe {
  public transform(heros: Hero[], filter: string) {
    if (!heros || !heros.length) return [];
    if (!filter) return heros;
    return heros.filter(h => h.name.toLowerCase().indexOf(filter.toLowerCase()) >= 0);
  }
}
  1. Use this Pipe inside of that dashboard.template
<h3>Top Heroes</h3>
<div class="grid grid-pad">
  <a *ngFor="let hero of (heroes | filterHeros : heroSearch.curSearch )"  [routerLink]="['/detail', hero.id]"  class="col-1-4">
    <div class="module hero">
      <h4>{{hero.name}}</h4>
    </div>
  </a>
</div>
<br />
<hero-search #heroSearch></hero-search>
  1. Change that HeroSearch component:
  private searchTerms = new Subject<string>();
  public curSearch: string; // !! NEW !!

  constructor(
    private heroSearchService: HeroSearchService,
    private router: Router) {}

  // Push a search term into the observable stream.
  search(term: string): void {
    this.curSearch = term;  // !! NEW !!
    this.searchTerms.next(term);
  }
  1. don't forget to add our Pipe to our app.module:
import { DashboardComponent, FilterHeroPipe }   from './dashboard.component';
import { HeroesComponent }      from './heroes.component';
import { HeroDetailComponent }  from './hero-detail.component';
import { HeroService }          from './hero.service';
import { HeroSearchComponent }  from './hero-search.component';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    InMemoryWebApiModule.forRoot(InMemoryDataService),
    AppRoutingModule
  ],
  declarations: [
    AppComponent,
    DashboardComponent,
    HeroDetailComponent,
    HeroesComponent,
    HeroSearchComponent,
    FilterHeroPipe
  ],
  providers: [ HeroService ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }