liveBook · Manning

ngOnChanges

As explained in Pro Angular 16

ngOnChanges is an Angular lifecycle hook method invoked before initialization and whenever a directive or component input property changes.

`ngOnChanges` is an Angular lifecycle hook for responding to input-property changes in a directive or component. Angular calls it once before `ngOnInit`, then again when an input changes. Updating an input does not, by itself, make a directive revise work it has already done: a class previously added to an element, for example, stays there until the directive removes it. section 14.3.3

When change details matter, accept a `SimpleChanges` parameter and look up the changed input by its property name. Its `SimpleChange` supplies `previousValue`, `currentValue`, and `isFirstChange()`. Check the first-change flag before undoing an earlier effect: on the initial call, the previous value may never have been applied. section 14.3.3

Table 14.4. The properties and method of the SimpleChange class
Name
Description
previousValue
This property returns the previous value of the input property.
currentValue
This property returns the current value of the input property.
isFirstChange()
This method returns true if this is the call to the ngOnChanges method that occurs before the ngOnInit method.

Use these `SimpleChange` members to distinguish an initial assignment from a later change and to replace an effect tied to the old value. section 14.3.3

Keep an attribute directive’s classes current

A table-cell directive receives a CSS class through `bgClass`. When adding a product changes the binding expression, Angular updates that input on existing directive instances. In `ngOnChanges(changes: SimpleChanges)`, read `changes["bgClass"]`; remove `previousValue` from the element’s class list only if this is not the first change and the class is present, then add `currentValue` if needed. New and existing elements can now reflect the same background-class decision. section 14.3.3

Show or remove a structural directive’s view

A conditional structural directive receives the result of a template expression as an input. Its `ngOnChanges` reads that input’s change: when the current value is true, it calls `ViewContainerRef.createEmbeddedView` with its `TemplateRef`; when a later value is false, it calls `clear()`. Here the notification changes which HTML view exists, rather than an element’s class. section 15.2.1

Listing 15.5. The contents of the structure.directive.ts file in the src/app folder
import {
    Directive, SimpleChanges, ViewContainerRef, TemplateRef, Input
} from "@angular/core";
 
@Directive({
    selector: "[paIf]"
})
export class PaStructureDirective {
 
    constructor(private container: ViewContainerRef,
        private template: TemplateRef<Object>) { }
 
    @Input("paIf")
    expressionResult: boolean | undefined;
 
    ngOnChanges(changes:  SimpleChanges) {
        let change = changes["expressionResult"];
        if (!change.isFirstChange() && !change.currentValue) {
            this.container.clear();
        } else if (change.currentValue) {
            this.container.createEmbeddedView(this.template);
        }
    }
}

The directive listing puts the input, change lookup, first-change check, and view-container operations together. section 15.2.1

The same hook is useful in components whose inputs change without a new component instance. During navigation between URLs handled by one component, Angular can reuse it and update its route-derived inputs; selecting a product in `ngOnChanges` makes Previous and Next navigation update the form. For a child-route category, an ordinary input is not itself a signal: copying its changes into a signal lets a computed product count reflect the active category. section 25.3.1 section 25.4.2

Other input-driven work follows the same pattern. A two-way-binding directive uses `ngOnChanges` to copy a changed model value into an input element’s host-bound `value`; an input event and output property handle the reverse direction. A custom validation directive creates a new validator when its input value changes, then uses that validator when assessing a control. Use the hook for the response needed by the input change, not as a replacement for those separate event or validation mechanisms. section 14.6 section 22.3.1

How Pro Angular 16 covers it

How deep it goes
Explains call timing, `SimpleChanges` members, first-change handling, and worked directive updates; does not detail Angular’s internal change-detection process.
Examples
Uses changing table-cell classes, conditional embedded views, reused product forms, and category-filtered product counts.
What it assumes
Assumes familiarity with Angular directives, components, and input bindings while defining the change records and their first-change method.
What you can do after
Build it from scratch in a directive or component to replace prior effects when bound inputs change.
How it connects
Connects input properties with `ngOnInit`, `SimpleChanges`, structural directives, `ViewContainerRef`, routing, and signals.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Pro Angular 16. The section links point to the parts of the book it draws on.