One of my latest assignments was to develop a custom drop-down component which supports both single and multiple selections.

As always, I will share some tips with you in the hope that you will learn new things.

Let’s begin by preparing the ground with two key components — we need a dato-select and dato-option components.

dato-select

#Tip 1

Since it’s a drop-down that supports multiple selection, I need to add a checkmark that indicates whether an option is selected.

One way to achieve this is by adding a type input() and according to its value show and hide the markup.

Yeah, it will work, but the disadvantage of this approach is that we add one more check per option to Angular, so in a dropdown with 10,000 options we added 10,000 more checks, and this is only one ngIf ; usually it will be accompanied with ngClass , ngStyle , etc.

In my case performance is very important, so I decided to split the multi-option to a different component that inherits from the single-option to avoid redundant checks.

Also, there are still parts of the markup that both have in common, so I’ll use template strings to keep my code DRY.

#Tip 2

The previous change brought with it a new problem. Let’s say I want to use the multi-select dropdown:

This will not work as the ContentChildren decorator is looking for DatoOptionComponent . If we want a reference to the option-multi components we need to add a different ContentChildren query.

But now we have to maintain both. Luckily we can solve this more elegantly with the help of Angular DI.

We can tell Angular — when you need DatoOptionComponent use DatoOptionMultiComponent .

#Tip 3

I was not satisfied yet. I wanted to use the same selector — dato-option — for both single and multiple drop-down components. So I changed the multi-option selector to be the same.

But now I have a problem. Angular doesn’t allow duplicate selectors and throws an error:

More than one component matched on this element.

Make sure that only one component’s selector can match a given element.

The way I solved it is by leveraging the fact that Angular supports the :not CSS selector. (along with other useful selectors)

Now we can stick with the same selector and add attribute when we need multi-option . This feels more appropriate, rather than introducing a brand new selector.

#Tip 4

The drop-down comes with a search box that is performing an internal search by default. We also need the option to perform a server-side search.

One way to achieve this is to create both an input() and output() :

But it feels like input is redundant and could be avoided; We can make do with knowing if someone is listening to the search event and based on that deciding whether to activate the internal search or not.

Every event emitter maintains a list of its observers. If we have at least one observer, it means that someone is subscribed.

🚀 In Case You Missed It

Akita : One of the leading state management libraries, used in countless production environments. Whether it’s entities arriving from the server or UI state data, Akita has custom-built stores, powerful tools, and tailor-made plugins, which all help to manage the data and negate the need for massive amounts of boilerplate code.

: One of the leading state management libraries, used in countless production environments. Whether it’s entities arriving from the server or UI state data, Akita has custom-built stores, powerful tools, and tailor-made plugins, which all help to manage the data and negate the need for massive amounts of boilerplate code. Spectator : A library that runs as an additional layer on top of the Angular testing framework, that saves you from writing a ton of boilerplate. V4 just came out!

: A library that runs as an additional layer on top of the Angular testing framework, that saves you from writing a ton of boilerplate. V4 just came out! And of course, Transloco: The Internationalization library Angular 😀

Follow me on Medium or Twitter to read more about Angular, Vue and JS!