Back to the homepage
Angular

Work smart, not hard – use Directive Composition API

In this article, you will find out what directive composition api is, why it took so long to be released, what problems it solves and what are its benefits and downsides. 

So, what is directive composition API? It’s a feature which allows you to compose directives with other directive, and.. that’s all! Seems basic, right? We could wonder, shouldn’t this feature be available since the early releases of Angular? This question has been around for a while, more precisely since 23rd May of 2016, when this issue was created, and this date coincides with the publication of Angular 2 first release candidate, which occurred in May 2016.

Why did it took so long?

The Recently mentioned issue was really popular across the angular community, and nearly  1.5 years later, a light at the end of the tunnel appeared. The creator of angular announced that after the introduction of the ivy compiler it will be more feasible.

After Ivy introduction in Angular 8, the community refreshed the issue and again asked for upcoming plans regarding this feature, and several months later, they got it – supporting such a feature would need some major engineering because of not compatible data structures. At last, on 13th November of 2020, directive composition was included in the official roadmap. With the 15th angular version, the long-awaited feature is finally introduced.

What problems directive composition solves? 

Let’s take a look at a use case. Imagine that you have three components

GIF

which share some functionality – color change (all of them), disabled state (button and toggle).

The most basic way to achieve this is to set up inputs for each of the components.

This approach violates DRY principle, so let’s take a different approach.

One of possible solutions is to use inheritance. We can create a Base Component, which each component will extend.

n that case, the spinner component has support for a disabled state, which is irrelevant for it, and overall, it is not the best practice to expose an api which will not be used.

To eliminate that, we could create two directives – Disable Directive and Color Directive. This way our code will be granulated for each functionality.

These directives will always be used within the scope of the component. Image that there is a lot of toggle instances: 

appColor and appDisable are quite redundant in a template, which is not really convenient to read, and here Directive Composition API comes handy.

Since Angular 15, there is a new property called hostDirectives. It allows you to specify an array of directives, which should be applied to our components. You can also set aliases for inputs and outputs to prevent conflicts between directive and host elements. It is important to remember that directives within hostDirectives have to be standalone.  

Now let’s take a look on our toggles

It’s much more readable! 

In our case, we composed directives with components, but it is also possible to compose directives with other directives. 

Here, we’ve got ToggleThemeDirective, which is composed of ColorDirective, DisableDirective, and also has its own functionality. After that, we just have to apply our ToggleThemeDirective as follows: 

Directives’ execution order

Host Directives have the same lifecycle as other components and directives in a template. It is important to remember that constructor execution, lifecycle hooks and bindings of host directives always occur before the directive or component which they are applied to. 

Let’s analyze the execution order of the Toggle Component with ToggleThemeDirective. This directive, as shown earlier, is composed of Disable, Color directives with some additional functionality. Let’s assume that those directives have only an ngOnInit lifecycle hook implemented.

Execution order would look like that: 

  1. Disable directive constructor execution
  2. Color directive constructor execution
  3. ToggleTheme directive constructor execution
  4. Disable directive ngOnInit 
  5. Color directive ngOnInit 
  6. ToggleTheme directive ngOnInit 
  7. Disable directive host bindings application
  8. Color directive host binding application
  9. ToggleTheme directive host binding application

Performance

While this feature offers great convenience, it can also lead to memory-related challenges if not used thoughtfully. For example, let’s take a look at the Toggle Component. It is composed of two directives, resulting in the creation of three objects after rendering, including the toggle object. This might not pose a noticeable issue for a small number of toggles, but when dealing with a larger quantity, such as within a substantial table, the impact becomes evident.

Summary

Directive composition API is a powerful, long-anticipated feature that can be used to improve your code quality and readability. However, its utilization should be approached with care, as it may introduce performance issues in scenarios where it is not well-suited.

Thanks for reading!

About the author

Łukasz Myszkowski

Angular Developer at House of Angular. A software developer who has been delving into Angular since the beginning of his career. Future owner of a shiba inu

Don’t miss anything! Subscribe to our newsletter. Stay up-to-date with the latest trends, tips, meetups, courses and be a part of a thriving community. The job market appreciates community members.

Leave a Reply

Your email address will not be published. Required fields are marked *