Mandatory Inputs in Angular v16
Angular 16 has officially shipped, and it brings along a range of useful capabilities and enhancements aimed at improving the overall developer workflow. This article takes a closer look at the latest Input syntax.
In Angular, Input serves as a decorator that links a component property with a DOM property in the template. During change detection, Angular monitors the bound DOM property for any updates and syncs the component property accordingly, guaranteeing that it stays current.
Consider the following usage of a component:
<app-child [name]="'John'"></app-child>
Here, the DOM property name is connected to a component property, and inside the component, the value John is accessible.
From the component class point of view, it looks like this:
@Component({
selector: 'app-child',
template: `Name: {{name}}`
})
class ChildComponent {
@Input() name: string;
}
Previously, there was no straightforward mechanism to enforce that the name property was provided by the parent component, which fell short of ideal.
<app-child></app-child>
Such code runs without any errors, but the rendered template will lack a name. To work around this, one could enforce the property within the selector.
@Component({
selector: 'app-child[name]',
})
class ChildComponent {
@Input() name: string;
}
Still, repeating that for every individual input property can become quite repetitive and time-consuming.
Making Inputs Required
Fortunately, that challenge is behind us now! Angular 16 introduces the concept of required inputs.
Inputs can now include an extra configuration flag to mark them as mandatory. As a result, you get a compile-time error when a value is not supplied for that input. Here’s how it looks:
Required input 'name' from component ChildComponent must be specified
This is the new syntax in action:
@Component({
selector: 'app-child',
template: `Name: {{name}}`
})
class ChildComponent {
@Input({ required: true }) name: string;
}
The required option remains optional, so you can continue to define "optional" inputs in the same way as before.
@Component({
selector: 'app-child',
template: `Name: {{name}}`
})
class ChildComponent {
// required input
@Input({ required: true }) name: string;
// basic input, not really required
@Input() lastName: string;
}
Input Aliasing
There is also a notable scenario involving input aliasing, where you might choose to use a different name for the DOM property than the component property it is tied to.
To achieve that, you could add an optional alias for the DOM property binding, as demonstrated here:
@Input() name: string;
@Input('lastname') surname: string;
When binding the surname property, you would need to reference the lastname property in the template.
<app-child name="John" lastname="Doe"></app-child>
Starting with Angular 16, you can also apply an alias using the updated syntax by passing a configuration object to the Input, as shown below:
@Component({
selector: 'app-child',
template: `Name: {{heroName}}`
})
class ChildComponent {
// required input with alias
@Input({ required: true, alias: 'name'}) heroName: string;
// basic input with alias
@Input({alias: 'lastname'}) heroSurname: string;
}
Have a great time exploring everything Angular 16 has to offer! ?
