08 May 2023
2 min

Required Inputs in Angular v16

Angular 16 is now available, bringing with it a host of great features and improvements to the developer experience. In this document, we'll take a closer look at the new Input syntax.

Input is an Angular decorator that allows us to bind a component's property to a DOM property in the template. When Angular runs change detection, it checks for changes in the bound DOM property and updates the component's property if necessary, ensuring it is always up to date.

Let's consider an example of using a component:

<app-child [name]="'John'"></app-child>

The DOM property name is bound to a component's property, and within the component, we can use the value John.

Here is an example from the component's class perspective:

@Component({
  selector: 'app-child',
  template: `Name: {{name}}`
})
class ChildComponent {
  @Input() name: string;
}

However, there was no simple way to ensure that the name property is passed from the parent, which was not ideal.

<app-child></app-child>

The code will work without any errors, but the rendered template will be missing a name. A workaround for this is to ensure that the selector requires that property.

@Component({
  selector: 'app-child[name]',
})
class ChildComponent {
  @Input() name: string;
}

However, adding this for every input property can be a tedious process.

Required Inputs

Fortunately, that's a thing of the past! Angular 16 introduces required inputs.

Now, inputs can take an additional configuration option that makes them required. This means that we will get an actual compile-time error if we don’t specify a value for that input. Here's an example:

Required input 'name' from component ChildComponent must be specified

This is what the new syntax looks like:

@Component({
  selector: 'app-child',
  template: `Name: {{name}}`
})
class ChildComponent {
  @Input({ required: true }) name: string;
}

The required option is optional, so we can still have "optional" inputs 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;
}

Aliasing

There is also an interesting case of aliasing inputs, where we want to have a different name for the DOM property than the name of the component's property that is bound to it.

To accomplish this, we can add an optional alias for binding the DOM property, as shown below:

@Input() name: string;
@Input('lastname') surname: string;

To bind the surname property in the template, we would have to use the lastname property.

<app-child name="John" lastname="Doe"></app-child>

From Angular 16, it is possible to add an alias using the new syntax. This can be done by including a configuration option 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 fun and enjoy Angular 16 features! ?

Frequently asked questions

How do I make an input required in Angular?

Set the required option in the decorator: @Input({ required: true }) name: string;. Angular then reports a compile-time error when a parent template uses the component without specifying a value for that input, instead of silently rendering an empty value. This check was introduced in Angular 16, so the option requires Angular 16 or later.

How did developers make an input required before Angular 16?

Before Angular 16 there was no built-in option, so the common workaround was to restrict the selector to require the attribute, such as selector: 'app-child[name]'. That forces the attribute to be present, but you must repeat this for every input, which is tedious. The required: true option in Angular 16 replaces this workaround with a compile-time check.

How do I alias an input with a different name in Angular 16?

Use the alias property in the @Input() configuration object, such as @Input({ alias: 'lastname' }) heroSurname: string;. The parent template then binds to lastname while the component class uses heroSurname. The same object can be combined with required: true, for example @Input({ required: true, alias: 'name' }). Before Angular 16, you had to pass the alias as a string argument, like @Input('lastname').

Can I mix required and optional inputs in the same Angular component?

Yes, you can mix them freely in one component. The required option is optional, so a plain @Input() stays optional and behaves as before, while @Input({ required: true }) enforces a value at compile time. For example, name can be required and lastName a basic input in the same class.

Share this post

Sign up for our newsletter

Stay up-to-date with the trends and be a part of a thriving community.