Diego Perez
November 09, 2020
Note: This article has been archived as it may contain features or techniques not supported with the latest version of Cosmic.
![cover image](https://imgix.cosmicjs.com/e89a72b0-1d4f-11eb-8ec3-0f4c230fe58a-cosmic-commerce-filters.png?w=1000&auto=format&dpr=2)
* This article will assume some basic knowledge of Angular and CMS so it can focus on the specific task at hand. Feel free to ask me about any specifics on the implementation you may find unclear
TL; DR
Take a look at:
What are we going to build?
This site will be based on a previous example - a headless ecommerce website - the purpose of which is to show how we can offer a customized experience for everyone. I strongly recommend that you read the first article, as we will work on top of what was built there. This time, we will add filtering functionality to showcase the Cosmic Advanced Queries feature. Our data will be stored and served by Cosmic and we will use Angular for our Front-End.
Preparing our bucket
The first thing we'll do is prepare our Cosmic bucket. We already have the following three object types:
- Categories
- Products
- Users
Each now will include a attribute, and each will include a attribute. These attributes will give us more to work with when building the filters.
We will also create a new type:
- Price filters
Each will have a and attribute. This new type will allow us to define price ranges to then use in the filter. There are other options to do this, as we could directly filter by all the different prices contained in the products, but this approach will give us (and the potential editor/merchandiser setting everything up) more flexibility on what we want to show the customer.
If you are as lazy as I am, you can always replicate the demo bucket by installing the app.
Updating the models
We need to reflect the changes to the bucket into our models. This will be the model for the price filters:
And, of course, we need to also update our product and category models:
Modifying the service
In order to take full advantage of the advanced queries, we will create a new method on our service:
*Note that the only difference with the old is the inclusion of the optional parameter.
Also, let's create a method to get our new price filters:
Creating the product filter component
Now we have a method to query products in an advanced manner, but we still need to construct the query, so let's build a component to allow the user to select the different filtering options.
We want to allow the customer to select different categories, colors and price ranges, for that, we will subscribe to our service and assign the results to a map that will store a pair of ; that way we can keep track of the user selections.
*The reasoning behind dividing categories between root/no-root is because I want to provide the user with a visual hint as to what this categories model looks like, but it's not relevant to the task.
Now, this is how the html will look:
All the change events look the same, they just mark the element as selected/unselected on the map (this is bound to the checkbox value, so there is no need to modify the DOM manually) and trigger a filter update:
* And so on...
Now, let's look at . This method will review what's currently selected on the maps (thanks to the help of aux methods , etc. and build our query.
Wrapping it all together
Did you notice we are emitting the query? Now it's time to go to our product listing and modify how it request the products to accommodate all the changes we made. First of all, let's update the HTML to include our new filter component.
Now we just need to define the method for our event, it looks like this:
And that's all. With just a couple updates on our previous headless eCommerce application, we've been able to add a pretty powerful filter component that would help our customers find the product they are looking for.
Interested in more articles like this? Check out Cosmic articles for more tutorials like this one, or join us in the Slack community, where hundreds of devs like you are discussing the future of Headless websites.