Discover how @ContentChild unlocks powerful ways to control content inside your Angular components effortlessly!
Why @ContentChild and content projection in Angular? - Purpose & Use Cases
Imagine building a reusable Angular component that needs to access and interact with parts of the content passed inside it by its user.
You try to grab elements manually from the DOM or pass data through complex inputs, but it quickly becomes messy and hard to maintain.
Manually querying or manipulating projected content is fragile and breaks encapsulation.
It leads to tightly coupled code that is hard to reuse or update.
You lose the power of Angular's clean component communication and lifecycle management.
@ContentChild lets your component easily access and interact with specific parts of the projected content.
It keeps your code clean, maintainable, and leverages Angular's powerful content projection system.
const el = document.querySelector('.projected-item'); // fragile and outside Angular's control
@ContentChild('projectedItem') projectedItem!: ElementRef; // Angular manages access safelyYou can build flexible, reusable components that adapt to whatever content users project inside them, with clean and safe access to that content.
A modal dialog component that projects custom header and footer content, and uses @ContentChild to control buttons inside the projected footer.
Manual DOM access for projected content is fragile and hard to maintain.
@ContentChild provides a clean way to access projected content inside Angular components.
This enables flexible, reusable components with safe interaction with user-provided content.
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
