I have created a demo project: https://stackblitz.com/edit/angular-e6pqlb?file=src%2Fcontent-host%2Fcontent-host.component.ts
Please open above link and check console printed values to understand my point below.
So, if you check src/main.html, content projection is used.
input property called inputValue is provided from AppRootComponent to the projected content component ContentViewComponent.
<app-content-host>
<app-content-view #testContent [inputValue]="inputValue"></app-content-view>
</app-content-host>
Projected component ContentViewComponent is having a simple paragraph inside its template
<p>{{ inputValue }}</p>
And I am trying to observe value inside paragraph using ContentChild and from direct DOM API.
export class ContentHostComponent implements AfterContentInit {
@ContentChild('testContent', { read: ElementRef }) contentChild: ElementRef;
ngAfterContentInit(): void {
console.log(document.body.innerHTML);
const innerHTML = this.contentChild.nativeElement.innerHTML;
console.log('inner HTML inside ngAfterContentInit : ', innerHTML);
}
ngAfterContentChecked(): void {
console.log(document.body.innerHTML);
const innerHTML = this.contentChild.nativeElement.innerHTML;
console.log('inner HTML inside ngAfterContentChecked : ', innerHTML);
}
}
I am unable to understand behaviour of the ngAfterContentInit and ngAfterContentChecked.
What I had understood was: Once projected content is rendered fully (i.e. change detection ran and DOM and component class are in sync) then after ngAfterContentInit method will be called.
Which implies content inside paragraph should NOT be empty if accessed inside ngAfterContentInit method.
Which implies, the paragraph element in should have value testValue
But that is not the case. paragraph is loaded with empty value.
Also, the same thing is printed for the first ngAfterContentChecked method call.
Which confuses me more. because I though ngAfterContentChecked is called after change detection is completed and DOM view and component class are in sync.
So, After change detection is over, empty paragraph should be loaded with value received as input from AppRootComponent(means 'testValue').
But again that is not the case.
Finally, Paragraph is filled with value when ngAfterContentChecked is called second time.
So, how Angular behaves in ngAfterContentInit and ngAfterContentChecked? Where my understanding went wrong? Angular docs says below things:
ngAfterContentInit() -->
Respond after Angular projects external content into the component's view, or into the view that a directive is in.
See details and example in Responding to changes in content in this document.
ngAfterContentChecked -->
Respond after Angular checks the content projected into the directive or component.
See details and example in Responding to projected content changes in this document.
I could not find specific details about above observation.