Gabriela Mendes
Gabriela Mendes

Reputation: 301

@Input() with null values on Angular 9 after update from 6.1

Something change in @Input() usage on child components? Some of my child components get the values null, but if a put IvyCompiler: false they start to work again and receive values normally. I read this on the docs, but for me isn't clear what change for @Input() and the usage on child components:

Unbound inputs for directives (e.g. name in ) are now set upon creation of the view, before change detection runs (previously, all inputs were set during change detection).

https://angular.io/guide/ivy-compatibility#changes-you-may-see

Upvotes: 2

Views: 5957

Answers (1)

Poul Kruijt
Poul Kruijt

Reputation: 71911

Like I already mentioned in my component. Your component's inputs are depending on each other in the setter. For instance, you have this piece of code:

@Input()
set show(show: boolean) {
  if (show === true && this.action === "update") {
    this.exchange();
  }
  this._show = show;
}

There is actually a specific order in which inputs get set at component creation. I can't remember which belongs to which version, but they did change this behavior with ivy. So either it depends on the order in which you define it in the parent template, or it depends on the order in which inputs are defined in the component itself.

But like i mentioned before, your code should not depend on this behavior, and you should move this logic to the ngOnChanges hook. This hook will be called first, even before the ngOnInit. In here you can be sure that all the inputs that are defined in the parent template are set. That would change your code to:

ngOnChanges(changes: SimpleChanges): void {
  // here both `show` and `action` input will be set at the first `ngOnChanges` call  
  if (changes.show && this.show && this.action === 'update') {
    this.exchange();
  }
}

Be aware though that this will only get called when the show input changes externally, not from within the component itself. For this you need to change your components logic to manually check for what the action is and call exchange()

Upvotes: 3

Related Questions