The Component Lifecycle
PlantTimer shows "watered 3 hours ago" and ticks every minute. It needs its plant before it can start, and it must stop ticking when the user leaves the page. Angular tells a component when these moments arrive through lifecycle hooks: methods it calls at fixed points.
The rule
Construct to exist, init to start, destroy to clean up.
The main hooks, in the order Angular calls them:
| Hook | When | Typical use |
|---|---|---|
constructor |
Class created | Inject services; nothing else |
ngOnChanges |
An input changed (also before init) | React to new input values |
ngOnInit |
Once, after the first inputs are set | Start work that needs inputs |
ngAfterViewInit |
Once, after the template and children render | Touch elements found by viewChild |
ngOnDestroy |
Just before removal | Stop timers, release resources |
There are also ngDoCheck, ngAfterContentInit, ngAfterContentChecked and ngAfterViewChecked for rarer cases.
import { Component, OnDestroy, OnInit, input, signal } from '@angular/core';
@Component({
selector: 'app-plant-timer',
template: `<p>Watered {{ minutesAgo() }} minutes ago</p>`,
})
export class PlantTimer implements OnInit, OnDestroy {
plant = input.required<Plant>();
minutesAgo = signal(0);
private timerId = 0;
ngOnInit() {
this.tick();
this.timerId = setInterval(() => this.tick(), 60_000);
}
ngOnDestroy() {
clearInterval(this.timerId);
}
private tick() {
const ms = Date.now() - this.plant().lastWatered.getTime();
this.minutesAgo.set(Math.floor(ms / 60_000));
}
}Implementing the OnInit and OnDestroy interfaces is optional, but it lets TypeScript catch a misspelled hook name.
Signal-era helpers cover the same moments: inject(DestroyRef).onDestroy(...) registers cleanup from anywhere, and afterNextRender(...) runs code once the browser has drawn the component.
The shortcut
Sort every piece of setup code by what it needs. Needs only services? Constructor. Needs inputs? ngOnInit. Needs rendered elements? After the view. Starts something that keeps running? Pair it with cleanup straight away.
Inject the clock service
Needs nothing but DI, so the constructor (or a field with
inject).
The trap is reading a required input in the constructor. It is not set yet, and a signal input throws an error saying it has no value.
Drills
Answer fast — trust the rule.
Which hook runs first after the constructor when a component has inputs?
Where should you start work that needs the plant input?
A component starts setInterval but never clears it. What happens when it is removed?
When is an element found with viewChild first safe to use in the lifecycle hooks?
Remember
- Constructor to exist,
ngOnInitto start,ngOnDestroyto clean up. - Sort code by what it needs: services, inputs or rendered elements.
- Trap: reading inputs in the constructor, or starting timers with no cleanup.
