Skip to content

Lifecycle Hooks

Angular calls specific methods on a component at defined points in its life β€” creation, updates, and destruction β€” if you implement them. The most common: ngOnInit (after Angular first sets the component’s inputs β€” the standard place for initial setup, not the constructor), ngOnChanges (whenever an @Input() changes), and ngOnDestroy (right before the component is removed β€” the place to clean up subscriptions, timers, etc.).

import { Component, Input, OnInit, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
@Component({ selector: 'app-widget', template: `...` })
export class WidgetComponent implements OnInit, OnChanges, OnDestroy {
@Input() userId!: string;
private subscription?: Subscription;
ngOnInit() {
// runs once, after inputs are first set -- do initial data loading here
this.subscription = this.userService.getUser(this.userId).subscribe(/* ... */);
}
ngOnChanges(changes: SimpleChanges) {
// runs whenever an @Input() value changes, including the very first time
if (changes['userId']) {
console.log('userId changed to', changes['userId'].currentValue);
}
}
ngOnDestroy() {
// runs right before the component is removed -- always clean up here
this.subscription?.unsubscribe();
}
}

Putting initialization logic that depends on @Input() values in the constructor instead of ngOnInit() β€” Angular hasn’t set input values yet when the constructor runs, so they’ll be undefined at that point.

export class WidgetComponent {
@Input() userId!: string;
constructor(private userService: UserService) {
console.log(this.userId); // undefined -- inputs aren't set yet!
this.userService.getUser(this.userId); // fails, called with undefined
}
}
// Fix: move input-dependent logic to ngOnInit
export class WidgetComponent implements OnInit {
@Input() userId!: string;
constructor(private userService: UserService) {} // constructor: only DI, no input-dependent logic
ngOnInit() {
console.log(this.userId); // set correctly by now
}
}
  1. Why shouldn’t you rely on @Input() values inside a component’s constructor?

    AnswerAngular sets input values after the constructor runs, so they're still undefined at that point β€” input-dependent logic belongs in ngOnInit() instead.
  2. What is ngOnDestroy typically used for?

    AnswerCleanup β€” unsubscribing from Observables, clearing timers/intervals, and removing event listeners before the component is removed, to prevent memory leaks.
  3. Does ngOnChanges run on the very first input assignment, or only on subsequent changes?

    AnswerIt also runs on the first assignment (right before ngOnInit), not just on later changes.