0

im doing and angular 2 with material design application. This application is a trading card game database, where the users can search for cards. By now the database is local with json files. The thing is that I have an input where the user writes the "race" of the card and it's suposed to filter the grid of images to the cards that share that race.

The card class is this:

export class Card {
  name: string;
  attribute: string;
  type: string;
  racesOrTraits: string[];
  text: string;
  set: string;
  code: string;
  rarity: string;
  thumbnailImage: string;
  cardImage: string;
}

I have two components for the page, one is the card list to filter and other is the container with the sidenav where the inputs are.

The grid template is:

<div class="card-grid">
  <md-grid-list cols="4" rowHeight="500px" gutterSize="1em">
    <md-grid-tile *ngFor="let card of cards | searchFilter:searchedName | raceFilter:searchedRace " md-cols="4">
      <img src="{{card.thumbnailImage}}">
    </md-grid-tile>
  </md-grid-list>
</div>

And the container template is this:

<md-sidenav-container>
  <md-sidenav #sidenav id="right-sidenav">
    <!-- sidenav content -->
    <p>Search:</p>
    <md-input-container>
      <input mdInput placeholder="Card Name" [ngModel]="searchedName" (ngModelChange)="searchedName=$event">
    </md-input-container>
    <md-input-container>
      <input mdInput placeholder="Race" [ngModel]="searchedRace" (ngModelChange)="searchedRace=$event">
    </md-input-container>
  </md-sidenav>
  <!-- primary content -->
  <div class="content">
    <card-list [searchedName]="searchedName" [searchedRace]="searchedRace"></card-list>
  </div>
</md-sidenav-container>

As you can see in the grid template I created two pipes that filters the cards, the pipe for the name is working fine, so when I change the value in the name input the cards filter ok.

But the pipe for the array of races of each card is not workin fine. It filters the cards with the EXACT race and not the races that contains the input. For example, if there are some cards with the race: "Knight of the round table" and I write "Knight" in the input, nothing appears. I don't know how to build this pipe to work as the other.

The name pipe is:

@Pipe({
  name: 'searchFilter',
  pure: false
})
@Injectable()
export class SearchByNamePipe implements PipeTransform {
  transform(items: any[], name: any): any {
    if (name != undefined) {
      // filter items array, items which match and return true will be kept, false will be filtered out
      return items.filter(item => item.name.toLowerCase().indexOf(name.toLowerCase()) !== -1);
    }
    return items;
  }
}

The race pipe is :

@Pipe({
  name: 'raceFilter',
  pure: false
})
@Injectable()
export class SearchByRacePipe implements PipeTransform {
  transform(items: any[], race: any): any {
    if (race != undefined) {
      // filter items array, items which match and return true will be kept, false will be filtered out
      return items.filter(item => item.racesOrTraits.map(function (r: string) {
        return r.toLowerCase();
      }).includes(race.toLowerCase()));
    }
    return items;
  }
}

Hope i explained myself. Thanks in advance

1
  • 1
    as far as I know, array.includes looks for the exact item not a subset. btw, this method doesn't support IE. try to use indexOf instead. Commented Apr 6, 2017 at 18:46

1 Answer 1

3

You should be filtering it from raceOrTraits as below

transform(items: any[], race: any): any {
    let filteredItems : any[] = new Array();
    if (race != undefined) {
      // filter items array, items which match and return true will be kept, false will be filtered out
        items.forEach((card)={
            card.forEach((item)=> {
                let temp= item.racesOrTraits.toLowerCase().includes(race.toLowerCase());
                if(temp){
                    filteredItems.push(card);
                }
            })

        })
     return filteredItems;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! It helped a lot :D

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.