I have a list of Food Products assigned to multiple categories and a specific vendor. example:
I am pre-filtering the products based on logged in vendor. after that I want to filter the products based on categories clicked.
I am able to achieve this someway, but it is not a nice way to filter I believe. for prefiltering I am using this code in constructor:
this.foodItemCollection = this.afs.collection<FoodItem>('foodItems');
this.foodItems = this.foodItemCollection.valueChanges({ id: 'id'}).pipe(
map(foodItems => foodItems.filter(result => result.vendorName == this.currentUserName))
);
after that on clicking the categories like fastfood, seafood, chinese etc I am calling categoryFilter()
function.
the code of this function is like this:
categoryFilter(foodCategory:any){
console.log(foodCategory);
this.foodItems = this.foodItemCollection.valueChanges({ id: 'id'}).pipe(
map(foodItems => foodItems.filter(result =>
(((result.categories[0]==foodCategory.categoryName) || (result.categories[1]==foodCategory.categoryName))
&& (result.vendorName==this.currentUserName))
))
)
return this.foodItems;
}
there are multiple problems with this approach. 1.This is making a duplicate request to fetch the products which are already fetched. 2.If product contains more than 2 categories, it will fail.
CodePudding user response:
Create a single function that is called on ngOnInit
and during valueChanges
like so
justFilter() {
// assuming your using reactive forms.
const { foodCategory, itemName } = this.formGroup.value;
this.foodItems = this.foodItemCollection.valueChanges({ id: 'id' }).pipe(
map((foodItems) =>
foodItems.filter(
(result) =>
result.vendorName == this.currentUserName &&
//filter using multiple values here!
(
(foodCategory.categoryName
? result.categories.includes(foodCategory.categoryName)
: true) &&
(itemName ? itemName === result.itemName : true)
)
// && and so on, you can write as many filters as you want!
)
)
);
}