Understanding Angular's Component Lifecycle
Angular's lifecycle hooks are fundamental to building robust, performant web applications. Understanding when each hook fires enables developers to initialize data at the right moment, avoid timing-related bugs, and optimize change detection performance.
Angular components go through a predictable lifecycle from creation to destruction. During this lifecycle, Angular provides specific hooks that allow developers to execute code at precise moments. These hooks are essential for proper component initialization, DOM manipulation, and resource cleanup.
For developers working with multiple frameworks, understanding Angular's approach compared to React provides valuable perspective on component lifecycle management patterns.
Angular provides eight lifecycle hooks that fire in a specific sequence
ngOnChanges
Fires when @Input() properties change value. First hook during initialization.
ngOnInit
Fires once after Angular initializes all input properties. Ideal for component setup.
ngDoCheck
Fires during every change detection cycle. Use for custom change detection.
ngAfterContentInit
Fires after projected content is initialized. @ContentChild queries are resolved here.
ngAfterContentChecked
Fires after Angular checks projected content. Can fire many times per lifecycle.
ngAfterViewInit
Fires after component view and children are ready. @ViewChild queries are resolved here.
ngAfterViewChecked
Fires after Angular checks the view. Keep operations lightweight.
ngOnDestroy
Fires just before component destruction. Essential for cleanup to prevent memory leaks.
ngAfterContentInit
The ngAfterContentInit hook fires after Angular has initialized all content that was projected into the component via <ng-content> tags. This hook is unique because it deals with content projection, not the component's own template.
When to Use ngAfterContentInit
- Accessing
@ContentChildand@ContentChildrenqueries - Manipulating projected content before the view renders
- Initializing logic that depends on projected content
This hook fires only once, after the first change detection cycle completes for projected content. Understanding when to use this hook versus ngAfterViewInit is critical for avoiding timing bugs in your Angular applications.
1import { AfterContentInit, ContentChild, Directive } from '@angular/core';2 3@Directive({4 selector: '[appProjectedContent]'5})6export class ProjectedContentDirective 7 implements AfterContentInit {8 9 @ContentChild('projected') 10 projectedContent: ElementRef;11 12 ngAfterContentInit() {13 // Content projected via <ng-content>14 // is now available15 console.log('Projected content:', 16 this.projectedContent);17 }18}ngAfterViewInit
The ngAfterViewInit hook fires after Angular has fully initialized the component's view and all child components. This is the hook to use when you need to manipulate the DOM or access child component references.
When to Use ngAfterViewInit
- Accessing
@ViewChildand@ViewChildrenqueries - DOM manipulation using ElementRef or native elements
- Initializing third-party libraries that require DOM access
- Setting up child component configurations
This hook fires after ngAfterContentInit, ensuring the component's complete view hierarchy is ready. For applications requiring extensive DOM manipulation, proper use of this hook is essential for performance and stability.
1import { AfterViewInit, ViewChild, 2 Component, ElementRef } from '@angular/core';3 4@Component({5 selector: 'app-child',6 template: '<div #childContent>7 Child content8 </div>'9})10export class ChildComponent 11 implements AfterViewInit {12 13 @ViewChild('childContent') 14 childContent: ElementRef;15 16 ngAfterViewInit() {17 // The component's view and all18 // child views are now ready19 console.log('View initialized:', 20 this.childContent.nativeElement);21 }22}The Execution Order
The key distinction is that ngAfterContentInit fires BEFORE ngAfterViewInit. This is because Angular processes projected content before it processes the component's own template and child components.
Complete Lifecycle Sequence
- Constructor - Component instance created
- ngOnChanges - @Input properties set (if applicable)
- ngOnInit - Component initialized
- ngAfterContentInit ← Projected content ready
- ngAfterViewInit ← Component view and children ready
- ngAfterContentChecked - Content verified
- ngAfterViewChecked - View verified
- ngOnDestroy - Component destroyed
Practical Implications
@ContentChildqueries are resolved inngAfterContentInit@ViewChildqueries are resolved inngAfterViewInit- Attempting to access
@ViewChildinngAfterContentInitwill result in undefined - DOM manipulation should only occur in
ngAfterViewInitor later hooks
ngOnChanges
Fires when an @Input() property changes value. Provides a SimpleChanges object with current and previous values.
Use for: Detecting input changes, triggering reload logic
ngOnChanges(changes: SimpleChanges) {
if (changes['data']) {
console.log('Changed from:',
changes['data'].previousValue);
console.log('Changed to:',
changes['data'].currentValue);
}
}
Best Practices for Performance
Minimize Work in Change Detection Hooks
The hooks that fire during change detection (ngDoCheck, ngAfterContentChecked, ngAfterViewChecked) can execute many times per second. Keep operations lightweight:
- Use
ChangeDetectionStrategy.OnPushto reduce unnecessary checks - Implement equality checks before performing expensive operations
- Use
markForCheck()anddetach()strategically
Proper Resource Cleanup
Always clean up resources in ngOnDestroy:
- Unsubscribe from observables to prevent memory leaks
- Clear intervals and timeouts
- Close WebSocket connections
- Remove event listeners
Avoid DOM Manipulation Before View Initialization
Never manipulate DOM elements before ngAfterViewInit. The view is not guaranteed to be ready.
Use ContentChild and ViewChild Appropriately
@ContentChild/@ContentChildrenavailable inngAfterContentInit@ViewChild/@ViewChildrenavailable inngAfterViewInit- Use
{ static: true }for queries needed inngOnInitfor static content
Conclusion
Angular's lifecycle hooks provide precise control over component behavior throughout its existence. By understanding when each hook fires and what operations belong in each, developers can:
- Build more predictable components with clear initialization and cleanup logic
- Avoid timing-related bugs by using the right hook for each operation
- Optimize application performance by minimizing work in change detection hooks
- Create cleaner, more maintainable code that follows Angular best practices
The distinction between ngAfterViewInit and ngAfterContentInit is particularly important--understanding this difference prevents common bugs and ensures code executes at the appropriate time. With proper use of lifecycle hooks, Angular applications become more robust, performant, and easier to maintain.
For teams building modern web applications, mastering these patterns is essential. Our web development services include Angular architecture review and implementation support to help you build better applications.
Frequently Asked Questions
Sources
- Angular.dev: Component Lifecycle - Official Angular documentation on lifecycle hooks and their execution order
- Angular.dev: AfterContentInit API - Official API reference for ngAfterContentInit
- Stack Overflow: Angular AfterViewInit vs AfterContentInit - Community discussion on the key differences between these hooks