@ContentChild helps you get a reference to something passed inside your component from outside. Content projection lets you put any content inside your component's tag, like putting a photo inside a frame.
@ContentChild and content projection in Angular
import { Component, ContentChild, AfterContentInit, ElementRef } from '@angular/core'; @Component({ selector: 'my-frame', template: `<ng-content></ng-content>` }) export class MyFrameComponent implements AfterContentInit { @ContentChild('insideRef') insideElement!: ElementRef; ngAfterContentInit() { // use insideElement here } }
@ContentChild looks for a child element or directive inside the projected content.
Use ngAfterContentInit lifecycle hook to safely access the projected content reference.
#insideRef that @ContentChild can find.<my-frame> <p #insideRef>This is inside content</p> </my-frame>
#insideRef inside the projected content.@ContentChild('insideRef') insideElement: ElementRef;<ng-content></ng-content>
This example shows a MyFrameComponent that projects any content inside a blue border box. It uses @ContentChild to get the paragraph inside and logs its text after content initializes.
import { Component, ContentChild, AfterContentInit, ElementRef } from '@angular/core'; @Component({ selector: 'my-frame', template: ` <div style="border: 2px solid blue; padding: 1rem;"> <h3>Frame Component</h3> <ng-content></ng-content> </div> ` }) export class MyFrameComponent implements AfterContentInit { @ContentChild('insideRef') insideElement!: ElementRef; ngAfterContentInit() { console.log('Projected content text:', this.insideElement.nativeElement.textContent.trim()); } } @Component({ selector: 'app-root', template: ` <my-frame> <p #insideRef>This text is projected inside the frame.</p> </my-frame> ` }) export class AppComponent {}
Always use ngAfterContentInit to access @ContentChild because the content is not ready before that.
If the projected content changes dynamically, consider using @ContentChildren or other strategies.
Content projection keeps your component flexible and reusable by letting others decide what to put inside.
@ContentChild gets a reference to a single element inside projected content.
Content projection lets you insert any content inside your component's tag using <ng-content>.
Use ngAfterContentInit to safely work with projected content references.
Practice
@ContentChild do in a component?Solution
Step 1: Understand content projection
Content projection allows inserting external content inside a component using<ng-content>.Step 2: Role of @ContentChild
@ContentChild gets a reference to a single element or directive inside that projected content.Final Answer:
It gets a reference to a single element inside the projected content. -> Option CQuick Check:
@ContentChild = reference to projected element [OK]
- Confusing @ContentChild with @ViewChild
- Thinking it creates new elements
- Assuming it projects content instead of referencing it
@ContentChild to get a reference to a template variable named myRef?Solution
Step 1: Correct syntax for @ContentChild selector
The selector must be a string matching the template variable name, so it should be quoted: 'myRef'.Step 2: Static option usage
Static option is optional and usually false by default; not required here.Final Answer:
@ContentChild('myRef') myElement!: ElementRef; -> Option AQuick Check:
Use quotes around template variable name in @ContentChild [OK]
- Omitting quotes around the selector string
- Using # inside the selector string
- Confusing static option necessity
@Component({ selector: 'child-comp', template: `` })
export class ChildComp {
@ContentChild('proj') projElement!: ElementRef;
ngAfterContentInit() {
console.log(this.projElement.nativeElement.textContent);
}
}And usage:
Hello World
What will be logged to the console?
Solution
Step 1: Understand content projection and @ContentChild
The<p #proj>is projected inside<ng-content>. @ContentChild('proj') gets its reference.Step 2: ngAfterContentInit timing
ngAfterContentInit runs after projected content is initialized, soprojElementis defined and accessible.Final Answer:
Hello World -> Option AQuick Check:
Projected element text logged correctly [OK]
- Trying to access projElement before ngAfterContentInit
- Assuming @ContentChild does not find projected elements
- Confusing @ViewChild with @ContentChild
@Component({ selector: 'proj-comp', template: `` })
export class ProjComp {
@ContentChild('item') itemRef!: ElementRef;
ngOnInit() {
console.log(this.itemRef.nativeElement.textContent);
}
}And usage:
Test
What problem will occur when running this code?
Solution
Step 1: Lifecycle hook timing for @ContentChild
@ContentChild references are not available in ngOnInit; they become available in ngAfterContentInit.Step 2: Accessing itemRef in ngOnInit
Accessing itemRef in ngOnInit causes it to be undefined, leading to runtime error when accessing nativeElement.Final Answer:
Error because itemRef is undefined in ngOnInit -> Option BQuick Check:
Use ngAfterContentInit for @ContentChild access [OK]
- Accessing @ContentChild in ngOnInit
- Assuming @ContentChild is available immediately
- Ignoring lifecycle hook order
Options:
A) Use
@ContentChildren('para') and highlight the first in the list.B) Use
@ContentChild('para') and add #para to the first paragraph only.C) Use
@ViewChild('para') inside the component template.D) Use
@ContentChild without a selector and highlight all paragraphs.Solution
Step 1: Understand multiple projected elements
When projecting multiple elements with the same template variable, use @ContentChildren to get all references.Step 2: Highlight the first paragraph
@ContentChildren returns a QueryList; you can access the first element and apply highlight logic.Final Answer:
Use @ContentChildren('para') and highlight the first in the list. -> Option DQuick Check:
Multiple projected elements need @ContentChildren [OK]
- Using @ContentChild for multiple elements
- Using @ViewChild for projected content
- Omitting selector in @ContentChild
Ready to prove it?
Pass the test and this pattern moves unknown
