1

Let's assume we have an Interface Customer:

export interface Customer {
    name: string;
    age: number;
    phone: string;
}

Now we have a parent component and we want to pass an instance of Customer to the child component:

<child-component [customer]="instanceOfCustomer"></child-component>

After that we need to use @Input decorator to get the data in the child component. (We assume passing the instance is mandatory to use this component and this component will not work without passing the instance)

@Input() customer:Customer;

The problem is that we need to initialize customer somewhere and I think there are 3 approaches to avoid the error in Typescript:

  1. Initializing an empty customer in the constructor:

    this.customer = {
        name: "";
        age: 0;
        phone: "";
    }
    
  2. Change strictPropertyInitialization to false

  3. Just adding the ! prefix (Which I think I should use because no one should use this child component without passing the relative customer)

    @Input() customer!:Customer;
    

I want to know what approach should I use to avoid property initialization error in case of using @Input decorator.

4
  • I edited the question to make it more detailed. So I don't think it's opinion based because the semantic of using Input decorator is always the same or at least it's most of the time the same. Especially when the passed object is mandatory. Commented Mar 13, 2022 at 15:16
  • I wouldn't use options 2 or 3. There is a time between the construction of the component and the initialization of the input. I would use @Input() customer?: Customer; Commented Mar 13, 2022 at 15:21
  • But ? means it's optional. Obviously it's not optional. So it's semantically wrong, isn't it? @jabaa Commented Mar 13, 2022 at 15:31
  • From TypeScript perspective, the property is optional. The property is uninitialized until AfterViewInit. ? doesn't say anything about whether the @Input is optional. Accessing the property before AfterViewInit should cause an TypeScript error. ! hides these errors. Commented Mar 13, 2022 at 15:33

2 Answers 2

2

you should use setter https://angular.io/guide/component-interaction#intercept-input-property-changes-with-a-setter

or you can also use your 3rd approach.

there is already some answers for this too.

refer below answers for more details :

Make directive @Input required

Sign up to request clarification or add additional context in comments.

Comments

2

To avoid TS from complaining I'll suggest initializing it like this:

@Input() customer: Customer | null = null;

Using null will stop the compiler from complaining when you pass the input through the async pipe (the async pipe returns something like T | null).

Also by doing that you'll have to make sure that you account for null values wherever you use that property, so fewer errors to deal with in production if something goes wrong let's say.

1 Comment

While this is a good practice, you might run into some trouble when trying to use this with an [(ngModel)] For example, if you write in your template: [(ngModel)]="customer.name" it might break if customer would be null. Of course one could argue that the smart component responsible for setting the value of customer should prevent the rendering of the child components if that would be the case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.