AcademyAngular
Attribute Fallthrough and ngOnChanges
A class or attribute a caller puts on a component's host element falls through by default; @HostBinding sets one from inside. ngOnChanges reports what changed.
2 min readUpdated 3 exercises
Attributes fall through to the host element automatically
An attribute or class a caller writes directly on a custom element — <app-badge class="urgent"> — lands on that component's actual host element by default, with no wiring required on the component's side. The trap is assuming a class or style written inside the component's own template overrides that: it does not override it, it coexists with it, which is how a badge ends up with classes on the wrong element — the caller's class="urgent" sits on the host, while the component's internal template applies its own classes to a child <span>, and the two never actually combine into the single element the design expected.
@HostBinding sets a property or class on the host explicitly
To make the component itself react to its own state — not markup a caller wrote, but a class the component decides to add based on an @Input() — @HostBinding binds directly to the host element from inside the class:
@Input() urgency: 'low' | 'high' = 'low';
@HostBinding('class.is-urgent')
get isUrgent(): boolean {
return this.urgency === 'high';
}A badge that "never reflects urgency on its own host" is usually urgency logic that lives in the component's own template — a class binding on an inner element — when the design actually needs the host element itself to carry that class, which only @HostBinding (or the equivalent host: {} metadata) can do.
ngOnChanges receives every @Input() that changed, keyed by name
ngOnChanges(changes: SimpleChanges) fires whenever any @Input() is reassigned from outside, with a SimpleChanges object keyed by the input's actual property name:
ngOnChanges(changes: SimpleChanges): void {
if (changes['temperature']) {
const { previousValue, currentValue, firstChange } = changes['temperature'];
}
}A trend indicator that "reads the wrong key" is exactly this: changes['temp'] when the actual @Input() is named temperature, or the reverse — the object silently has no matching property, so the check evaluates as falsy and the indicator never updates. The other classic bug here is trusting previousValue on the very first change: firstChange is true precisely because there was no real previous value, and code that compares against it anyway is comparing against undefined.
What interviewers check
Whether you know that host bindings and template-internal classes are two separate targets that do not automatically merge, and whether you check firstChange before trusting previousValue in ngOnChanges — the bug that skips it looks identical to a correct implementation until the component's very first render.
Now practice it
1 quiz · 2 drillsReading this page is the cheap half. These are the exercises that make you use it.
- Attribute Fallthrough & Host BindingsProFix a badge whose caller-supplied classes end up on the wrong element, and one that never reflects urgency on its own host.DrillSolve · MediumDrillSolve · Medium
- ngOnChanges & SimpleChangesProFix a temperature trend indicator that reads the wrong SimpleChanges key and inverts its own first-change check.DrillSolve · MediumDrillSolve · Medium
- Services & DI · Standalone & TokensHarder DI and injector questions at the level where host-scoped providers and component internals intersect.QuizTake · HardQuizTake · Hard
Read next
Dependency Injection and Injection Tokens
inject() asks Angular's container for a shared instance instead of constructing one privately. InjectionToken<T> does the same for values that aren't classes.
2 min
Lifecycle Hooks and Custom Directives
ngOnInit is where setup belongs, ngOnDestroy where it gets torn down; a custom attribute directive follows the same discipline for its own listeners.
2 min