Hey devs! đź‘‹
As promised, we're continuing our series on Angular decorators. But today, we’re doing something a bit different. A friend recently pointed me to a more modern and DI-friendly alternative to the traditional @Attribute
decorator—say hello to HostAttributeToken
.
Let’s dive into how this new approach works and how you can use it to write cleaner, more testable Angular code.
What is HostAttributeToken
?
HostAttributeToken
allows you to inject static attribute values from the host element in a more flexible, testable, and dependency injection (DI)-friendly way.
In older Angular versions, you’d use the @Attribute
decorator for this. While that works fine, HostAttributeToken
provides several advantages — especially when working with standalone components or modern DI patterns.
Syntax
new HostAttributeToken('attrName');
Example: Replacing @Attribute
with HostAttributeToken
We’ll reuse an example we discussed earlier using the @Attribute
decorator — but this time, we’ll refactor it using HostAttributeToken
.
Both approaches achieve the same functionality, but HostAttributeToken
allows the attribute value to be injected using the inject()
function, outside of the constructor.
Directive: FontType
import { AfterViewInit, Directive, ElementRef, HostAttributeToken, inject, OnInit, Renderer2 } from '@angular/core';
@Directive({
selector: '[fontType]'
})
export class FontType implements OnInit, AfterViewInit {
private renderer = inject(Renderer2);
private el = inject(ElementRef);
public font: string = inject(new HostAttributeToken('font'));
constructor() {
console.log(this.font);
}
ngOnInit(): void {
switch (this.font) {
case 'italic':
this.renderer.setStyle(this.el.nativeElement, 'color', 'red');
break;
case 'bold':
this.renderer.setStyle(this.el.nativeElement, 'color', 'green');
break;
case 'underline':
this.renderer.setStyle(this.el.nativeElement, 'color', 'orange');
break;
default:
console.log('Font not provided');
}
}
ngAfterViewInit(): void {
console.log('Before changing the attribute value:', this.font);
this.renderer.setAttribute(this.el.nativeElement, 'font', 'some_random_value');
console.warn('After changing the attribute value:', this.font);
}
}
Component Usage
import { Component } from '@angular/core';
import { FontType } from '../../directive/role';
@Component({
selector: 'app-about',
standalone: true,
imports: [FontType],
template: `
<h1><u>About Me</u></h1>
<p>
I’m a <b>frontend developer</b> and
<b fontType font="bold">freelancer</b> passionate about building
beautiful, responsive, and user-friendly web interfaces.
</p>
<p>
I specialize in <b><u fontType font="underline">HTML</u></b>,
<b><u fontType font="underline">CSS</u></b>,
<b><u fontType font="underline">JavaScript</u></b>,
and modern frameworks like <b>React</b> and <b>Vue</b>. I enjoy turning
complex problems into simple, elegant solutions.
</p>
<p>
<i fontType font="italic">I believe that great design is just as important as great code</i>,
and I’m always exploring <u>new technologies</u> and tools to enhance user experience.
</p>
<p>
Whether it’s building from scratch or improving an existing project,
I’m ready to help.
<b><i><u>Let’s create something amazing together!</u></i></b>
</p>
`,
styleUrls: ['./about.scss'],
})
export class AboutComponent {}
Output
Pros and Cons of HostAttributeToken
âś… Pros:
-
DI-friendly: Works seamlessly with
inject()
, even outside constructors. - Flexible: Compatible with standalone components and modern DI patterns.
- Testable & Mockable: Easily overridden in unit tests or custom providers.
- Versatile: Usable in factories, services, and other DI contexts.
⚠️ Cons:
- Static Only: Still reads a static value from the attribute — it’s not reactive to changes made after initialization.
Conclusion
HostAttributeToken
is a modern and powerful replacement for @Attribute
. If you're embracing Angular’s latest DI improvements, this is definitely a pattern worth adopting.
Have you tried this approach yet? Let me know your thoughts and experiences in the comments below! 🚀
✍️ Author: Vetriselvan
👨‍💻 Frontend Developer | Code Lover | Exploring Angular’s future
Top comments (0)