DEV Community

Gaëtan Redin
Gaëtan Redin

Posted on • Originally published at Medium on

How to Handle Required Inputs in Angular

Handling Required Inputs in Angular Directive and Component.

Hey, this article presents tips for handling required inputs in a Directive or a Component.

The classic approach could be implementing the ngOnInit method and throwing errors when the input value is not set.

public ngOnInit(): void {
  if (this.myInput === undefined) {
    throw new Error('input myInput is required for MyDirective');
  }
}
Enter fullscreen mode Exit fullscreen mode

But I don’t want to have to write this for all my required properties… So yep, I’m a bit lazy … ^^ But the main goal is to simplify the code.

I recently found an interesting way to do it just once!

Do you know the concept of Typescript decorators?

V1 class decorator

That’s what I would like to code:

@Directive(...)
@RequiredInputs('input1', 'input2')
export class MyDirective {
  @Input()
  public input1!: unknown;

  @Input()
  public input2!: unknown;

  @Input()
  public input3Optional ?: unknown;
}
Enter fullscreen mode Exit fullscreen mode

Here’s how to implement the decorator which allows doing that:

export function RequiredInputs(...inputs: string[]) {
return function (constructor: any) {
const original = constructor.prototype.ngOnInit;
constructor.prototype.ngOnInit = function () {
inputs.forEach((input: string) => {
if (this[input] === undefined) {
throw new Error(`property ${input} is mandatory ${constructor.name}`);
}
});
if (original && typeof original === 'function') {
original.apply(this, arguments);
}
};
};
}

Now you will get an error for input1 and input2 if it’s not set on the directive using:

<span myDirective></span> // throw Error
<span myDirective input1="1"></span> // throw Error
<span myDirective input1="1" input2="toto"></span> // No Error
Enter fullscreen mode Exit fullscreen mode

As it’s said in comment by a reader you also can handle this with using the compoent/directive’s selector like this:

@Directive({
  selector: '[myDirective][input1][input2]',
  ...
})
Enter fullscreen mode Exit fullscreen mode

But the error message will not be consistent. The directive will not be recognized by Angular if you do it like this and that’s all. Whereas here with the decorator you will have an explicit message for the case. So yes there are many ways to handle it, just choose your prefer way.

V2 property decorator

Here’s the code:

export function Required() {
return function (target: any, key: string): void {
const NG_ON_INIT = 'ngOnInit';
// eslint-disable-next-line @typescript-eslint/ban-types
const original: Function | null = target[NG_ON_INIT];
target[NG_ON_INIT] = function () {
if (this[key] === undefined) {
throw new Error(`Property ${key} is required`);
}
if (original) {
original.apply(this);
}
};
};
}

You juste have to use it like this:

@Component(...)
class MyComponent {
  @Input()
  @Required()
  public myProperty: unknown;

  ...
}
Enter fullscreen mode Exit fullscreen mode

Thanks for reading.

What about you? How do you handle this use case? Please tell me.

Learn More

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (0)

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay