One of the most confusing parts of creating an Shopify store is: filtering and sorting the products, in a fast scalable way. Today I’d like to show you how I filter my products in Shopify. Shopify’s domain language for a group of products is called a “collection”. I’ll refer to this feature we are working on as a collection for the rest of the post.
Note: Shopify has a built in way to query products using url params and tags. If you have a very simple collection and only have a few small filters this could be a better approach. If you need more control over the filters and don’t want to refetch products or possibly you have a more headless approach my filter might be a better option. For a great explanation of Shopify tag filtering see christopherdodd.
Back to business. Say you have a collection of the timeless product, the T-shirt, your business requirements are to filter these shirts by color. So, you write a little filter like this when the user clicks a red swatch.
A couple days later your project manager says “shouldn’t we filter by size as well” so you think to yourself ok so now I need to make a filter so that I can find a “red” / “small” T-shirt. You assume the logical approach and filter products down having to be red AND small. You are proud of your work but before the end of the day you get pulled aside by your project manager and she says you need to add yet another filter. “We need to filter by material now too, and while you are at it, let's filter by different color combinations”. This filter is beginning to get complex and you are also thinking now how many more filters are they going to add. Can’t we find a way to add filters more easily?
I saw this filter design pattern a while back online somewhere. I’d credit the author if I could remember where, but until then, I’ll just give a shout out to the mystery man.
The MegaFilter class accepts the products array and a specification parameter. I will shed more light on the specification parameter in the coming steps. But basically this little bit of code orchestrates the entire filter.
The OrSpecification class accepts custom specifications we will create in the next step. This class loops through all of the specifications it has been given and checks if at least one of the specifications are met on a product. For example if we made a specification that the shirt needed to be blue and another one that needed it to be red and fed both of those specifications to the OrSpecification, then it would filter products that are blue or red.
The AndSpecification class also accepts custom specifications. It works exactly like the OrSpecification but instead of checking if only one specification was met it makes sure all specifications are met on the product to pass.
Now to the fun part! This is where we will start writing actual filters. These are the specifications that we will pass into the “and” and “or” specification classes. Each of these classes will accept different parameters depending on what attribute you want to compare the product data to. Here is an example of a color filter that just accepts a string for the color.
Pretty easy right? So let’s put it all together. Using the orchestrating classes in the code below ( I’m going to put this all on one file for ease of use. I’m also going to throw in a price specification for another example.) we can apply our custom specifications to our mega filter.
Hopefully this filter pattern can be of use to you. I'm sure you have guessed it by now but this pattern could be used to filter really anything else you wanted. I used this pattern just the other day to filter stores on a map for a store locator ( I'll post more on that later).
That's all for now, shoot me a message if you have any questions!