Improving DX with new Angular @Input Value Transform

Embrace the Future: Moving Beyond Getters and Setters! Learn how to leverage the power of custom transformers or the build in booleanAttribute and numberAttribute transformers.

emoji_objects emoji_objects emoji_objects
Kevin Kreuzer

Kevin Kreuzer

@kreuzercode

18.11.2023

3 min read

Improving DX with new Angular @Input Value Transform
share

Angular 17 has rolled out, and it’s packed with some really cool stuff. There’s a bunch to get excited about, like the new control flow, deferred loading, and some slick improvements in server-side rendering.

But there’s this one feature that’s not making as much noise yet, and it’s pretty neat: @Input Transforms. In this blog post, we’re going to take a look at this hidden gem and see how it can make handling input data in your apps a whole lot smoother. Let’s dive in and check out what this feature has to offer!

This feature has been available since version 16.1

@Input Transforms

Let’s take a look at a simple component that displays characters.

@Component({
  standalone: true,
  //...
  template: `<h1>{{ character.name }}`
})
export class CharactersComponent {
  @Input({ required: true }) character!: Character;
}

In our CharactersComponent, we accept a required character @Input. The goal is to display the character’s name in uppercase. With Angular 17, we can implement this feature by leveraging the new transform feature.

Alternatively, we could also use a pipe for this transformation.

function characterNameUppercase(character: Character): Character {
  return {
    ...character,
    name: character.name.toUpperCase()
  }
}
    
@Component({
  standalone: true,
  //...
  template: `<h1>{{ character.name }}`
})
export class CharactersComponent {
  @Input({ $required: true, transform: characterNameUppercase }) 
  character!: Character;
}

In our example, we utilized a simple function that takes in a Character and returns a transformed Character with an uppercase name. The transform can be any function, which opens up a world of possibilities. Whether it’s formatting data, manipulating strings, or even more complex operations, everything is possible.

Build-in Transform Functions

Angular throws in two handy built-in transforms too — numberAttribute and booleanAttribute. Let’s take a quick look at how these built-in options can enhance our code.

numberAttribute

The numberAttribute transformer is a transformer that converts any @Input into a number.

@Component({
  standalone: true,
  selector: 'circle',
  //...
})
export class CircleComponent {
  @Input({ transform: numberAttribute }) 
  radius!: number;
}

With the numberAttribute transform in place we can use the component in two manners.

<!-- does not compile without the numberAttribute transform -->
<circle radius="100"/>

<!-- works with or without the numberAttribute transform -->
<circle [radius]="100"/>

booleanAttribute

The other build-in directive is the booleanAttribute function. A function that allows us to convert inputs to boolean's.

This can be very useful since it optimizes how we can apply flags on components.

@Component({
  standalone: true,
  selector: 'product',
  //...
})
export class ProductComponent {
  @Input({ transform: booleanAttribute }) 
  showDetails!: boolean;
}

With this code in place we can use the component in the following ways:

<!-- without the booleanAttribute this code would not compile -->
<my-product showDetails/>

<!-- without the booleanAttribute this code would not compile -->
<my-product showDetails="true"/>

<!-- works with and without the booleanAttribute transform -->
<my-product [showDetails]="true"/>

As you can see the booleanAttribute function simplifies usage and makes it possible to simply enable a flag by adding the flag name.

If you like this feature you are not alone, Angular already utilizes this feature internally in the router.

Build-in Transform Downsides

While the built-in transforms offer nice functionality, it’s important to acknowledge some downsides. Utilizing these transforms leads to the loss of type definitions, making the code more susceptible to typographical errors. This increased vulnerability to typos can inadvertently introduce bugs into the system.

Let’s again take a look at the product.component.

@Component({ 
  standalone: true,
  selector: 'my-product',
  //...
})
export class ProductComponent {
  @Input({ transform: booleanAttribute }) 
  showDetails!: boolean;
}

We could use this component in the following way.

  <my-product showDetails="falser"/>

In this scenario, not only is there a typographical error (we typed falser instead of false), but there’s likely also a bug. The goal seems to be to disable a flag, but due to the behavior of booleanAttribute, which converts any string not explicitly set to ”false” into true, the intended functionality may not be achieved as expected.

Integrating BooleanAttribute and NumberAttribute Into Existing Codebases

If you like this features you may want to use them accross your code base. But its a lot of effort, right? Well, don’t worry, I implemented some schematics to take care of this. The schematics will automatically add the booleanAttribute and numberAttribute transformers to inputs of type boolean or number. The schematics will merge the transformers with any existing input properties such as alias or required.

The schematics allow you to add either only booleanAttribute transformer or only numberAttribute transformer or both.

A transform transformer

Interested in the behind-the-scenes of this library? It was all put together live on my Twitch stream. Feel free to follow and join us for some relaxed, yet informative sessions on Angular and the latest in frontend development. Looking forward to seeing you there!

Do you enjoy the theme of the code preview? Explore our brand new theme plugin

Skol - the ultimate IDE theme

Skol - the ultimate IDE theme

Northern lights feeling straight to your IDE. A simple but powerful dark theme that looks great and relaxes your eyes.

Do you enjoy the content and think that your teammates or organization could benefit from more direct support?

Angular Enterprise Architecture Ebook

Angular Enterprise Architecture Ebook

Learn how to architect and scaffold a new enterprise grade Angular application with clean, maintainable and extendable architecture in almost no time!

Lots of actionable tips and pros & cons of specific decisions based on the extensive experience!

Get notified
about new blog posts

Sign up for Angular Experts Content Updates & News and you'll get notified whenever I release a new article about Angular, Ngrx, RxJs or other interesting Frontend topics!

We will never share your email with anyone else and you can unsubscribe at any time!

Emails may include additional promotional content, for more details see our Privacy policy.
Kevin Kreuzer - GDE for Angular & Web Technologies

Kevin Kreuzer

GDE for Angular & Web Technologies

Trainer, Berater und Senior Front-End Engineer mit Schwerpunkt auf dem modernen Web. Er ist sehr erfahren in der Implementierung, Wartung und Verbesserung von Anwendungen und Kernbibliotheken für große Unternehmen.

Kevin ist ständig dabei, sein Wissen zu erweitern und zu teilen. Er unterhält mehrere Open-Source-Projekte, unterrichtet moderne Webtechnologie in Workshops, Podcasts, Videos und Artikeln. Weiter ist er ein beliebter Referent auf Konferenzen. Er schreibt für verschiedene Tech-Publikationen und war 2019 der aktivste Autor der beliebten Angular In-Depth Publikation.

58

Blog posts

2M

Blog views

23

NPM packages

3M+

Downloaded packages

39

Videos

14

Celebrated Champions League titles

Responses & comments

Do not hesitate to ask questions and share your own experience and perspective with the topic

You might also like

Check out following blog posts from Angular Experts to learn even more about related topics like Angular !

Angular Signal Inputs

Angular Signal Inputs

Revolutionize Your Angular Components with the brand new Reactive Signal Inputs.

emoji_objects emoji_objects emoji_objects
Kevin Kreuzer

Kevin Kreuzer

@kreuzercode

24.01.2024

6 min read

Angular Material components testing

Angular Material components testing

How and why to use Angular Materials component harness to write reliable, stable and readable component tests

emoji_objects emoji_objects emoji_objects
Kevin Kreuzer

Kevin Kreuzer

@kreuzercode

14.02.2023

7 min read

Angular & tRPC

Angular & tRPC

Maximum type safety across the entire stack. How to setup a fullstack app with Angular and tRPC.

emoji_objects emoji_objects emoji_objects
Kevin Kreuzer

Kevin Kreuzer

@kreuzercode

24.01.2023

6 min read

Stärken Sie Ihr Team mit unserer umfassenden Erfahrung

Unsere Angular Experten haben viele Jahre damit verbracht, Unternehmen und Startups zu beraten, Workshops und Tutorials zu leiten und umfangreiche Open-Source-Ressourcen zu pflegen. Wir sind sehr stolz auf unsere Erfahrung im Bereich des modernen Frontends und würden uns freuen auch Ihrem Unternehmen zum Aufschwung zu verhelfen.

or