7

I want to filter a list of JSON objects (Products) by the variable 'category' using a checkbox.

a porduct is a followed :

  {
  'bikeId': 6,
  'bikeName': 'Kids blue bike',
  'bikeCode': 'KB-3075',
  'releaseDate': 'June 28, 2016',
  'description': 'Kids blue bike with stabalizers',
  'category': 'kids',
  'price': 290.00,
  'starRating': 4.8,
  'imageUrl': 'https://openclipart.org/image/2400px/svg_to_png/1772/bike-kid.png'
}

My current ngFor Loop is as followed:

   <tr *ngFor="let product of products">
                       <td><img *ngIf='showImage' 
                         [src]='product.imageUrl' 
                        [title]='product.bikeName'
                        [style.width.px]='imageWidth'></td>
                       <td>{{product.bikeName}}</td>
                       <td>{{product.bikeCode}}</td>
                       <td>{{product.releaseDate}}</td>
                           <td>{{product.price}}</td>
                           <td>{{product.starRating}}</td>
</tr>

And My current Check boxes are as followed:

 <input type="checkbox" name="All" value="true" /> Mens 
                <input type="checkbox" name="All" value="true" /> Womens 
                <input type="checkbox" name="All" value="true" /> Kids 

I ask this question because i have been searching forums all day to no avail. Some answers do answer it but when i test the code it's either outdated or just doesn't work. Any help would be appreciated.

  • Fire off a method to loop your array of objects and group them by "category" into the array that's feeding your ngfor that populates your list for the products object array. ....or are you asking for someone to do that for you? What have you tried? – Chris W. Oct 09 '18 at 16:34
  • Thanks for the help, any help is appreciate. Have i tried ? Yes. The hostility isn't necessary. –  Oct 09 '18 at 16:38
  • Aidan - Sorry wasn't meant to be interpreted as hostility, just inquiry. Cheers! – Chris W. Oct 09 '18 at 17:57

1 Answers1

5

Quite surprised you couldn't find an example online, as there are many ways to handle this problem and my answer is just one.

In this example I keep the source of products untouched, but create a second array with that will contain the products displayed. I bind each checkbox to a property of a filter model and when a change occurs I call filterChange() to update my filtered products array from that model.

You don't necessarily need NgModel and two binding and you could certainly dynamically generate the filters from an array which would probably be a good idea as your application grows. You could also use Observables, or create a Pipe to filter the array in NgFor. Really the possibilities are endless.

MyComponent.ts

export class MyComponent {
  filter = { mens: true, womens: true, kids: true };
  products: Product[] = []
  filteredProducts = Product[] = [];

  filterChange() {
    this.filteredProducts = this.products.filter(x => 
       (x.category === 'kids' && this.filter.kids)
       || (x.category === 'mens' && this.filter.mens)
       || (x.category === 'womens' && this.filter.womens)
    );
  }
}

MyComponent.html

<tr *ngFor="let product of filteredProducts"> <!-- ... --> </tr>
<!-- ... --->
<input type="checkbox" [(ngModel)]="filter.mens" (ngModelChange)="filterChange()" /> Mens 
<input type="checkbox" [(ngModel)]="filter.womens" (ngModelChange)="filterChange()" /> Womens 
<input type="checkbox" [(ngModel)]="filter.kids" (ngModelChange)="filterChange()" /> Kids
Daniel Gimenez
  • 18,530
  • 3
  • 50
  • 70
  • Thank you for the reply, it means allot. Just when I have all the code in the filteredProducts = [] = []; I'm getting an error :'property bikeid is missing type undefined' any help would be greatly appreciated. –  Oct 09 '18 at 16:59
  • I mistakenly used angle brackets when defining my arrays. Updated answer. – Daniel Gimenez Oct 09 '18 at 18:23
  • Thank you so much, it may not seem it but it helped allot and hopefully it can help others. –  Oct 09 '18 at 19:17
  • Indeed, it did help me too. The answer is clear, quick and simple to understand, and up voted +1 for both question and answer :) – Mr. Dang Mar 14 '20 at 22:10
  • @DanielGimenez this has helped me a great deal so thank you for this but I have a few issues that I would be grateful if you could help. 1st how do I reset it back to original list if I change any of the checkboxes and also instead of hardcoding 'kids' 'men' etc, I use an input field but it only filters on exact match. How can I get it to work if word is in lowercase or just has to be included in the category eg. I type men, it can return both mens and womens. – Siobhan Holubicka Sep 02 '22 at 07:36