Angular HostAttributeToken: the new way to inject attributes


Over the latest months Angular has been evolving rapidly, introducing new features and a ton of improvements, many of these with the aim of improving maintainability and performance.

In this article I want to introduce you to the latest addition brought by Angular v17.3.0: the new HostAttributeToken class.

This new API allows you to inject host attributes using the inject() function, similar to the functionality of the @Attribute decorator.

The @Attribute decorator is perhaps the lesser-known Angular decorators.
Therefore, before delving into how the HostAttributeToken class works, let’s take a moment to review the fundamentals.

@Attribute: do you really need an input?

Let’s start from a simple scenario in which you want to develop a component requiring a configurable property.

Specifically, you want to provide this property as a constant string literal, because it will not change throughout runtime:

 size="small" />

What you would normally do is to create an input for that property:

import { Component, Input } from '@angular/core';

export type DividerSize = 'small' | 'big';

  selector: 'my-divider',
  template: '
', standalone: true, }) export class MyDivider { @Input() size: DividerSize; }

Which is fine and works quite well. Perhaps too much…

Meme - Well done. BUT...

By creating an input, you are instructing Angular to create a binding to that property and check it during each change detection cycle.

That is really excessive, you only need that property to be checked once during component initialization. 🤯

To make this more performant you can instead inject the host-element attribute in the constructor thanks to the @Attribute decorator:

import { Attribute, Component } from '@angular/core';

export type DividerSize = 'small' | 'big';

  selector: 'my-divider',
  template: '
', standalone: true, }) export class MyDivider { constructor(@Attribute('size') size: string) {} }

Using @Attribute, Angular will read the value only once and never again.

Note: This approach works as well with Directives, feel free to give it a shot!!!

Now that we have covered the basics, let me introduce you to the main topic of this article: new HostAttributeToken class.

Meme - Finally, let's talk about new stuff!

Inject an Attribute using HostAttributeToken class

Since the release of Angular 14 there is now a cleaner approach to inject providers without using the constructor class: the inject() function.

Up until now, this inject() function allowed to inject easily components, directives and pipes, but it was missing a method to inject host attributes.

And that’s precisely why the HostAttributeToken class was introduced:

import { Component, HostAttributeToken, inject } from '@angular/core';

export type DividerSize = 'small' | 'big';

  selector: 'my-divider',
  template: '
', standalone: true, }) export class MyDivider { size: string = inject( new HostAttributeToken('size') ); }

By injecting an HostAttributeToken class within the inject function, you get the corresponding host-element attribute value.

This new API works similarly to @Attribute, with a notable difference: instead of returning null when the attribute is missing, it throws an error.

🔥 Error: NG0201: No provider for HostAttributeToken size found. 🔥

This change was made to align the behavior with other injection tokens.

Thanks for reading so far 🙏

I’d like to have your feedback so please leave a comment, like or follow. 👏

Then, if you really liked it, share it among your community, tech bros and whoever you want. And don’t forget to follow me on LinkedIn. 👋😁

Leave a Reply

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

Previous Post

Revolutionize your Website: Free Heat Maps, Recordings, Analytics & more

Next Post

Usando NextDNS CLI en tu red.

Related Posts