I created sorting sidebar which filter my product list based on category and price. Filtering by category works correctly.
I have a problem with filtering based on the price of the product.If I set the category to "Smartfons" and filter a product with a price higher than 2000, it will return Iphone X correctly in my case:
but when I change the filter to "All" I have this one phone and It should return 3 phones:
export class ProductComponent implements OnInit {
filteredProduct: Products[] = [];
products: Products[] = [];
currentSorting: string;
wrapper = true;
@ViewChild('filtersComponent')
filtersComponent: SortProductsComponent;
constructor(protected productsService: CategoriesProductsService) { }
sortFilters: any[] = [
{ name: 'Name (A to Z)', value: 'name' },
{ name: 'Price (low to high)', value: 'priceAsc' },
{ name: 'Price (high to low)', value: 'priceDes' }
];
priceFilters: any[] = [
{ name: 'All', value: 'all', checked: true },
{ name: 'Price > 2000', value: 'more_2000', checked: false },
{ name: 'Price < 500', value: 'less_500', checked: false }
];
ngOnInit() {
this.displayProducts();
}
displayProducts() {
this.productsService.getProducts().subscribe(product => {
this.products = product;
this.filteredProduct = product; });
}
onFilterChange(data) {
if (data.type === 'category') {
if (data.isChecked) {
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < data.filter.Products.length; i++) {
this.filteredProduct.push(data.filter.Products[i]);
}
} else {
this.filteredProduct =
this.products.filter(x => {
return x.CategoryId !== data.filter.Id; } );
}
} else if (data.type === 'price') {
this.filteredProduct = this.products;
if (data.isChecked) {
const priceFilter = data.filter.value;
if (priceFilter === 'all') {
this.filteredProduct = this.products;
} else if (priceFilter === 'more_2000' ) {
this.filteredProduct = this.products.filter(x => x.Price > 2000);
} else if (priceFilter === 'less_500' ) {
this.filteredProduct = this.products.filter(x => x.Price < 500);
}
}
}
}
SortProductComponent:
export class SortProductsComponent implements OnInit {
categoriesList: Categories[];
@Input()
priceFilters: any[];
// tslint:disable-next-line:no-output-on-prefix
@Output()
onFilterChange = new EventEmitter<any>();
showFilters = true;
sideShown = false;
constructor(private categoriesService: CategoriesProductsService) { }
ngOnInit() {
this.displayCategories();
}
displayCategories() {
this.categoriesService.getCategories().subscribe((data) => {
this.categoriesList = data;
});
}
onInputChange($event, filter, type) {
const change = $event.target.checked ? 1 : -1;
this.onFilterChange.emit({
type,
filter,
isChecked: $event.target.checked,
change
});
}
}
HTML template:
<h5>Filter by categories</h5>
<form >
<div class="category-filter filter-wrapper" *ngFor = 'let filter of categoriesList'>
<div class="custom-control custom-checkbox">
<label class="fake-checkbox">
<input type="checkbox" class="custom-control-input" checked (change)='onInputChange($event, filter, "category")'>
<span class="custom-control-label"> {{filter.Name}}</span>
<span></span>
</label>
</div>
</div>
</form>
<h5>Filter by price</h5>
<form *ngIf = "showFilters">
<div class="custom-filter filter-wrapper" *ngFor = 'let filter of priceFilters'>
<label class="fake-checkbox">
<input type="radio" name="price" [checked]='filter.checked' (click)='onInputChange($event, filter, "price")'>
<span class="circle"><span class="fill"></span></span>
<span class="label">{{filter.name}}</span>
<span></span>
</label>
</div>
</form>
Product class:
export class Products {
Id: number;
Name: string;
Description: string;
DetailedDescription: string;
Price: number;
IsNewProduct: boolean;
PromotionalProduct: boolean;
Image: string;
CategoryId: number;
}
I think that by using the filter () method, which returns a new array to me, the filter on the array works only once.
I would like my category and price filter to work just like on this page: https://carlosroso.com/angular2-shop
Any help is welcome