0

I ran into a mystery. I'm in an ngFor loop like in this example:

<div *ngFor="let rc of sortedKeys(ruleImplementations)">
    <vi-rule-contract [descriptor]="ruleDescriptors[rc]" [item]="action" [rc]="rc">
    </vi-rule-contract>
</div>

Only for one of those N number of created 'vi-rule-contract' components (a very specific one) ngOnInit will not be called only its ngOnChanges with new values for (descriptor, rc, item). For all other 'vi-rule-contract' ngOnInit will be called but never ngOnChanges. So here is my question:

Is there a case when ngOnInit on a component will never be called only its ngOnChanges?

PS Angular 6.1.10

risingTide
  • 1,754
  • 7
  • 31
  • 60
Hivaga
  • 3,738
  • 4
  • 23
  • 36
  • @Cyril, Hi I am sure I can provide a print screen of the console log. Full example won't be easy to provide since it is a big application. All of them are created and I can see the console logs. Only for one of them it skips the ngOnInit and goes to the ngOnChanges directly. Here a screenshot of the console log https://snag.gy/EJDrjC.jpg – Hivaga Mar 14 '19 at 20:32
  • 1
    Hivaga, The opposite happens to what you say. The most simple example is in https://stackblitz.com/edit/angular-ubxmkq?file=src%2Fapp%2Fapp.component.html. I supouse your problem is that there are a problem with your component – Eliseo Mar 14 '19 at 20:35
  • @Eliseo true in general case the ngOnInit is called always. Probably something fails in the execution on the component with particular data. This is legacy code I am trying to support it :) – Hivaga Mar 14 '19 at 21:27

1 Answers1

0

The problem is that you have a function defining your list which means that the ngFor is constantly re executing, this is extremely bad practice, angular is trying to save you by only instantiating the components once but changing the inputs.

Your fix here is to stop using a function in template, and just run it when needed.

<div *ngFor="let rc of sortedRuleImplementations">
    <vi-rule-contract [descriptor]="ruleDescriptors[rc]" [item]="action" [rc]="rc">
    </vi-rule-contract>
</div>

this.sortedRuleImplementations = this.sortedKeys(ruleImplementations);

I can't tell from your code when ruleImplementations changes, but you might do this in an observable subscription or something

bryan60
  • 28,215
  • 4
  • 48
  • 65