import { Component, ContentChild, AfterContentInit, ElementRef } from '@angular/core'; @Component({ selector: 'app-wrapper', template: `<div>Wrapper Start</div><ng-content></ng-content><div>Wrapper End</div>` }) export class WrapperComponent implements AfterContentInit { @ContentChild('projected') projectedContent!: ElementRef; ngAfterContentInit() { if (this.projectedContent) { this.projectedContent.nativeElement.textContent += ' (modified)'; } } } // Usage in parent template: // <app-wrapper> // <p #projected>Hello World</p> // </app-wrapper>
The @ContentChild('projected') decorator finds the element with the template reference #projected inside the content projected into <ng-content>. The ngAfterContentInit lifecycle hook runs after the content is projected, allowing modification of the projected element's text. So the paragraph text is changed to "Hello World (modified)" before rendering.
The @ContentChild references elements projected into the component's <ng-content>. These are not available during ngOnInit. Angular sets them after content projection is done, which happens before ngAfterContentInit. So this hook is the first safe place to access @ContentChild.
<child-comp> projected into a parent, which @ContentChild decorator correctly selects the child component instance?import { Component, ContentChild } from '@angular/core'; import { ChildComp } from './child-comp.component'; @Component({ selector: 'parent-comp', template: `<ng-content></ng-content>` }) export class ParentComp { // Which @ContentChild is correct? }
The @ContentChild decorator can take a component class type to select the first projected instance of that component. Using the class ChildComp directly is correct. Using a string selector or CSS class name does not select the component instance.
import { Component, ContentChild, AfterContentInit, ElementRef } from '@angular/core'; @Component({ selector: 'app-wrapper', template: `<ng-content></ng-content>` }) export class WrapperComponent implements AfterContentInit { @ContentChild('proj') proj!: ElementRef; ngAfterContentInit() { console.log(this.proj); } } // Usage: // <app-wrapper> // <p>Hello</p> // </app-wrapper>
The @ContentChild('proj') looks for an element with #proj inside the projected content. If the projected paragraph does not have #proj, the query returns undefined. The other options are incorrect because ngAfterContentInit runs after projection, @ContentChild works with native elements, and the selector can be a template reference string.
@ContentChild queries elements that are projected into the component from outside via <ng-content>. @ViewChild queries elements that are declared inside the component's own template. They serve different purposes and are not interchangeable.