Creating a Multi-Filter Function to Filter Out Multiple Attributes Using Javascript

When one filter just isn’t enough

Nate Park
Better Programming

--

http://www.techtalk.gfi.com/wp-content/uploads/2011/07/web-content-filtering-200x300.jpg

For the final project of a recent bootcamp, I was tasked with creating an eCommerce website where customers can buy children clothing. While building the site, my biggest challenge was writing a .filter function where customers can click on tags to narrow down their list of products.

Customers can click on any tags, my filter function will render only products that satisfy customers’ choice.

In this piece, I’ll be walking through my process and codes and the final outcome while detailing how to create a multi-filter function that compares all of a product’s attributes and customer’s chosen tags to output a filtered list of products.

What is .filter() in Javascript?

The filter() method creates a new array with all elements that pass the test implemented by the provided function. — MDN documentation

Accepting a function as an argument, using .filter() will return a new array with all elements that return true.

Product table design

Before diving straight into explaining, let's review the properties of the products we will be filtering.

Here are the values for each key:

Not only it was challenging because I wanted to create a dynamic filter function, but also because material is an array that contains multiple elements.

My Complete Codes

One feature of the website is that customers can see what tags they chose above search input. To cancel tags, simply click on chosen tags.

In order to render the chosen tags between the magnifier icon and searching section, I had to design my react’s state in a specific way. The “tag-collecting” section (small red rectangle) will collect any tags that customers clicked, meaning that when one of the tags are clicked, it triggers a callback, callFilterClickListener(), that sets the boolean state to true.

All tags that appear in the tag-collecting section are in `passingTags`

Because each element in each key has a different responsibility and because I required each of them to be clickable tags for customers, I had to write a very long script.

Each key has its own ‘div’ tag but calls the same function with different arguments.

Since customers can click on any of the tags to cancel them, including tags that are already chosen, I included another component that looks very similar to the above component.

.allFilterClickListener()

The function allFilterClickListener() dynamically takes an event and the name of the property as arguments (refer to the first image under My Complete Codes).

Side Note: React Doc recommends to use prevState when using .setState(). You can find more information in this link.

Let’s say a customer clicks on white, pink, cotton and girl. The function will search through the state, find the key called color and change the boolean value to true or false depending on the state of state. The process is then repeated for filtering material to cotton and gender with girl.

.filteredCollected()

This function returns collectedTrueKeys by looping through color, gender, material, and category separately and pushing the keys that have values that are true to each array. Since I selected white, pink, cotton, and girl, collectedTrueKeys , it will look like this.

.multiPropsFilter()

This is a function I found on GitHub. The function compares the two arguments, products and filters, and returns the only products that pass through the given filters.

However, simply copy-pasting the code from the resource was not enough because material is an array that contains multiple materials. Thus, in addition to the code, I added in from line 182 to 186. If one of the keys in the product is an array, it will loop through it again and will return anything that is true.

.searchProducts()

Because customers can search for products by typing, .searchProducts() handles filtering and searching simultaneously.

Then, the child component ProductContainer will receive the already-filtered list of products.

Summary

  1. Customers will trigger .allFilterClickListener(event, <key name>) when clicking on any filter tags.
  2. .allFilterClickListener() receives clicked tags and change the right state.
  3. .filteredCollected() loops through the state and collect any keys with values that are true.
  4. .multiPropsFilter() takes in all product list and filter to return the filtered product list.
  5. Because of the child component ProductContainer always call .searchProducts(), both number three and four will be responsive to changes.

Conclusion

It is just so amazing that I can do anything I want when using Javascript. I will still be able to get the desired outcome even if my material even more nested with arrays. The .filter() challenge for my last project as a bootcamp student helped my thinking process and was a great and enjoying experience that I will always keep with me as I move forward.

--

--