When we build a new component, we often design it around specific inputs, and sometimes the component doesn't make sense without them.

Fortunately, Angular provides multiple techniques for enforcing that an input is supplied — let's examine them.

Table of Contents

Using NgIf

The simplest approach to render a component's template only when an input is populated is to verify it through the NgIf directive:

@Component({
  selector: 'app-with-required',
  standalone: true,
  imports: [NgIf],
  template: '<div *ngIf="isDefined">Value is: {{ value }}</div>'
})
export class WithNgIfComponent {
  @Input() value!: number;

  get isDefined(): boolean {
    return typeof this.value === 'number';
  }
}
Enter fullscreen mode Exit fullscreen mode

With this technique, Angular will leave the template out of the DOM whenever value is missing.

This effectively forces the @Input to be present for the UI to render, though it’s not necessarily the ideal solution for our use case.

For one thing, omitting the input won’t trigger any error message. If another developer wants to integrate our component, it would be far more helpful for it to clearly signal its dependencies rather than leave them to infer which properties are essential.

In addition, because supplying the value is not a hard requirement, value could still be undefined. That means any internal logic relying on it would have to include extra safety checks just to avoid runtime issues.

Using lifecycle hooks

We can resolve the first concern by having the component implement the OnInit lifecycle hook, then explicitly verify during initialization whether the input was actually delivered:

@Component({
  selector: 'app-with-ngoninit',
  standalone: true,
  template: '<div>Value is: {{ value }}</div>'
})
export class WithNgOnInitComponent implements OnInit {
  @Input() value!: number;

  ngOnInit(): void {
    if (this.value === undefined) {
      throw new Error('`value` is required');
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This approach improves things slightly—now, if the value is omitted, an error will appear in the console.

NgOnInit error

So we've made some headway, but it's still not ideal: even though we now actually get an error, it only surfaces during runtime. As a result, the component becomes harder to work with because its faulty behavior isn't detected until it's actually used.

Using the selector

Of course, it would be far more preferable to catch that error much sooner.

One approach to accomplish this is by leveraging the Angular Language Service and placing the input directly within the component's selector:

@Component({
  selector: 'app-with-selector[value]',
  standalone: true,
  template: '<div>Value is: {{ value }}</div>'
})
export class WithSelectorComponent {
  @Input() value!: number;
}
Enter fullscreen mode Exit fullscreen mode

This approach means that if the component is used without the required input being supplied, Angular will be unable to determine which component instance is being referenced.

With selector error

Passing the input to the component works as expected in this case as well.

That said, the error message you get is far from descriptive—it points to an unknown component rather than flagging the absent input.

One more thing worth keeping in mind is that Angular doesn’t connect the input in your selector to the @Input you declare. So if you rename it, you must also update the selector manually.

Using the required option

Every solution discussed so far involves some tradeoff:

  • With NgIf, you suppress the error but skip writing validation logic for the input
  • With OnInit, you confirm the value is present, though it costs you extra code
  • With the selector, you force the @Input to be used and get a compile-time error—but that error is vague, pointing to an unknown component rather than the missing property

The good news is that the Angular team has acknowledged this problem and plans to tackle it in the framework’s upcoming release, version 16.

GitHub logo feat(compiler): add support for compile-time required inputs #49468

This is a re-submit of #49453.

Adds support for marking a directive input as required. During template type checking, the compiler will verify that all required inputs have been specified and will raise a diagnostic if one or more are missing. Some specifics:

  • Inputs are marked as required by passing an object literal with a required: true property to the Input decorator or into the inputs array.
  • Required inputs imply that the directive can't work without them. This is why there's a new check that enforces that all required inputs of a host directive are exposed on the host.
  • Required input diagnostics are reported through the OutOfBandDiagnosticRecorder, rather than generating a new structure in the TCB, because it allows us to provide a better error message.
  • Currently required inputs are only supported during AOT compilation, because knowing which bindings are present during JIT can be tricky and may lead to increased bundle sizes.

Fixes #37706.

Instead of using a simple boolean parameter, you can pass an object literal to the @Input decorator to mark an input as required.

@Component({
  selector: 'app-with-required',
  standalone: true,
  template: '<div>Value is: {{ value }}</div>'
})
export class WithRequiredComponent {
  @Input({ required: true }) value!: number;
}
Enter fullscreen mode Exit fullscreen mode

Whenever the value is missing, Angular raises an error during compilation:

With required compilation error

This time, the error surfaces not only at compile time but also with clarity, pointing out the missing property, the component involved, and the exact line.

Leveraging an object literal to extend the current @Input behavior offers backward compatibility: existing solutions remain functional without modification, and once you migrate to Angular 16, you can adopt this enhancement in your project with minimal disruption.


Throughout this article, we explored four distinct techniques to enforce that an input is supplied to a component:

  • Using NgIf in the template for validation
  • Validating during component initialization via OnInit
  • Employing selector syntax to gain Angular Language Service assistance
  • Applying Angular 16's new required flag within @Input options

My preference leans toward the required flag, as it offers the clearest and most direct expression of the contract between the component and its consumers.

For a look at the resulting implementation, refer to the linked GitHub repository, which contains all components along with their usage examples.


I trust you gained something valuable from this read!


Photo by Sigmund on Unsplash