The Power of ViewChildren in Angular
We can use the ViewChildren
decorator to get the QueryList
of elements or directives from the view DOM. In this article, we’ll examine how can we leverage this technique in order to manage our application filters in a reusable, efficient and clean way.
Here is an illustration of the final result:
Imagine that we’re on a page that displays a list of resources and the users can filter the list by resource type
or by resource level
.
To inform the server how to filter the resource, we’ll use the query string style where we define what the current filters are. For example:
https://api.com/resources?type=video&level=beginner
Our goal:
Each time the user clicks on a filter we need to get the latest value from each filter and create the new query string.
Fortunately, we have an Rx operator precisely for this kind of functionality — combineLatest
.
Let me know when any Observable emits but also give me the latest value from the others. ( Array )
Let’s create the filters
component. This will be our final markup:
The Interfaces
The Filter
interface is mostly for the UI. The ActiveFilter
is for the server. The group
is referring to the query string key, for example:
https://api.com/resources?level=beginner
In the about URL, the group
is referring to level
.
The Filters Component
We have two Inputs
, the group name and array of filters.
The combineLatest
operator expects to receive a list of observables. We need to create an observable that will emit the active filter each time the user clicks on a filter.
But there is one catch, we need to get the initial data, so we also need to emit the value from each at the component initialization phase. We can tackle this problem with BehaviorSubject
.
BehaviorSubject
takes an initial value and emits it immediately.
We need to find the active filter
from the filters
Input; then we need to create our BehaviorSubject
and emit the current filter id
with the group
.
Now let’s check the HTML and add the click
event.
The code is straightforward, let’s move to the select()
method that will run each time the user clicks on a filter.
We need to change the active
state on every filter; then we need to emit the new active filter
.
The component is ready for use. Finally the fun part.
Now we need to get the observable from each filters
component. We are going to use the ViewChildren
decorator to grab the filters components from the current view.
Great! Now we have the filters instances so we can get access to the changeFilter
observable. The final step is to use combineLatest
.
Every time one of the filters emits value, we’re going to receive an array containing each filter value, transform them to a query string and send to our server.
That’s all.
You can extract this code to a self-contained module and use it.
Follow me on Medium or Twitter to read more about Akita, Angular and JS!
👂🏻 Last but Not Least, Have you Heard of Akita?
Akita is a state management pattern that we’ve developed here in Datorama. It’s been successfully used in a big data production environment for over seven months, and we’re continually adding features to it.
Akita encourages simplicity. It saves you the hassle of creating boilerplate code and offers powerful tools with a moderate learning curve, suitable for both experienced and inexperienced developers alike.
I highly recommend checking it out.