DEV Community

Cover image for Angular HostAttributeToken: the new way to inject attributes
Davide Passafaro
Davide Passafaro

Posted on • Originally published at codemotion.com

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:

<my-divider size="small" />
Enter fullscreen mode Exit fullscreen mode

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

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

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

@Component({
  selector: 'my-divider',
  template: '<hr [class]="size" />',
  standalone: true,
})
export class MyDivider {
  @Input() size: DividerSize;
}
Enter fullscreen mode Exit fullscreen mode

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';

@Component({
  selector: 'my-divider',
  template: '<hr [class]="size" />',
  standalone: true,
})
export class MyDivider {
  constructor(@Attribute('size') size: string) {}
}
Enter fullscreen mode Exit fullscreen mode

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';

@Component({
  selector: 'my-divider',
  template: '<hr [class]="size" />',
  standalone: true,
})
export class MyDivider {
  size: string = inject( new HostAttributeToken('size') );
}
Enter fullscreen mode Exit fullscreen mode

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. 👋😁

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

Cloudinary image

Optimize, customize, deliver, manage and analyze your images.

Remove background in all your web images at the same time, use outpainting to expand images with matching content, remove objects via open-set object detection and fill, recolor, crop, resize... Discover these and hundreds more ways to manage your web images and videos on a scale.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay