Tushar Khanna
Tushar Khanna

Reputation: 438

Why order of Instantiating of Angular Components is not in expected order with if condition?

I cannot find anywhere in the docs why the order of instantiating of Angular Components is not in expected order with if condition? I was expecting it to come in the same order as they are written in the console also. i.e 1 2 3 4 5 (HTML wise it is correct) but it is coming as 3 4 5 1 2

Although I have made assumption after observing this behavior that if condition delays execution comparing with without it but could not find the reason/documentation for it.

Slackblitz Link to verify this behavior: https://stackblitz.com/edit/angular-looping-data-sbnayy?file=app%2Fapp.component.html

enter image description here

Upvotes: 2

Views: 284

Answers (1)

Maxim  Dmitrachkov
Maxim Dmitrachkov

Reputation: 56

All structural directives act that way because they are based on <ng-template>

This:

<hello name="1" *ngIf="true"></hello>

just simplified syntax of

<ng-template [ngIf]="true">
    <hello name="1"></hello>
</ng-template>

<ng-template> won't be rendered while it's not instructed to do so.

What exactly happens in your case:

  1. app.component has created and comes through OnInit => DoCheck => AfterContentInit => AfterContentChecked lifecycle hooks.

  2. hello.components are content (children) of app.component and they shall be initialized, but under the hood *ngIf wraps "hello1" and "hello2" into <ng-template>. Remember that.

  3. Now app.component's children come through the same lifecycle hooks (OnInit to AfterContentChecked). Angular does not insert <ng-template>'s into the DOM but placeholder for that (you can see it in the document tree as a comment):

    <!--bindings={ "ng-reflect-ng-if": "true" }-->

  4. Then "hello3", "hello4" and "hello5" are initialized, inserted into the DOM and execute console.log(this.name)

  5. Time for ngIf directives and hello.components (3 to 5) initialize they own content. At this time hello.components (1 and 2) are initialized each inside their own ngIf directive, inserted into the DOM after their placeholders and also execute console.log(this.name)

  6. Then AfterViewInit => AfterViewChecked hooks bubbles up from the very deep children in the tree and you see rendered page

Upvotes: 2

Related Questions