In Angular, in what order do a component's lifecycle hooks run on first render, and which of them repeat on later checks?
answer
- changes, init, check
- content before view
- Init once, Checked every pass
- children finish before parent's view hooks
basics
~10 sFirst render: constructor, ngOnChanges (if inputs are bound), ngOnInit, ngDoCheck, ngAfterContentInit, ngAfterContentChecked, ngAfterViewInit, ngAfterViewChecked; ngOnDestroy runs once at removal. Later checks repeat ngOnChanges on input change, ngDoCheck and both Checked hooks.
solid answer
~40 sAfter the constructor, the first change-detection pass calls `ngOnChanges` (only when at least one input is bound), `ngOnInit`, `ngDoCheck`, `ngAfterContentInit`, `ngAfterContentChecked`, `ngAfterViewInit` and `ngAfterViewChecked`. The `Init` hooks run once. On later passes that refresh the view the component sits in, Angular calls `ngOnChanges` if an input changed, then `ngDoCheck`, `ngAfterContentChecked` and `ngAfterViewChecked`. Once the whole application has rendered to the DOM, `afterNextRender` callbacks run once and `afterEveryRender` callbacks run after each render. `ngOnDestroy` runs once before removal. With nesting, a parent's init and content hooks run before its children are checked, and the parent's `ngAfterViewInit` runs only after every child has finished its own view hooks.
code
ts · 19 linesimport {
AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit,
Component, DoCheck, OnChanges, OnDestroy, OnInit, input,
} from '@angular/core';
@Component({ selector: 'app-hook-probe', template: `<p>{{ label() }}</p>` })
export class HookProbe implements OnChanges, OnInit, DoCheck, AfterContentInit,
AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy {
readonly label = input('');
constructor() { console.log('constructor'); }
ngOnChanges() { console.log('ngOnChanges'); }
ngOnInit() { console.log('ngOnInit'); }
ngDoCheck() { console.log('ngDoCheck'); }
ngAfterContentInit() { console.log('ngAfterContentInit'); }
ngAfterContentChecked() { console.log('ngAfterContentChecked'); }
ngAfterViewInit() { console.log('ngAfterViewInit'); }
ngAfterViewChecked() { console.log('ngAfterViewChecked'); }
ngOnDestroy() { console.log('ngOnDestroy'); }
}go deeper
Recall the sequence changes, init, do-check, content init and checked, view init and checked, destroy, and that ngOnInit runs once after the first ngOnChanges.
Explain which hooks repeat, why content hooks precede view hooks, how parent and child hooks interleave, and when content and view query results become available.
Tie the order to real bugs: NG0100 from state changes in after-view hooks, DOM work that belongs in afterNextRender, costly per-check hooks, and code that wrongly depends on directive hook order.
Discuss how teams keep lifecycle logic small as signals and render callbacks take over, and which hooks a code review should question by default.
## The model: hooks ride along with change detection Angular keeps the DOM in sync by walking the component tree **from top to bottom**, checking each view's template bindings. This walk is **change detection**, and lifecycle hooks are methods Angular calls on components and directives at fixed points of the walk. Two vocabulary items make the order easy to remember: - **Content** is what a parent projects into the component through `<ng-content>`; content queries (`contentChild`) see it. - **View** is the component's own template and the children declared in it; view queries (`viewChild`) see it. Content comes from outside and is settled first; the component's own view is settled last. ## First render, step by step 1. `constructor`: plain class instantiation; bindings are not applied yet. 2. `ngOnChanges(changes)`: the first input values; called **only if at least one input is bound**. 3. `ngOnInit`: once, after the first input values are set, before the template renders. 4. `ngDoCheck`: on every check of this component, starting with this one. 5. `ngAfterContentInit`: once, after projected content is initialized; content query results are ready. 6. `ngAfterContentChecked`: after the content is checked. 7. `ngAfterViewInit`: once, after the component's own view and all child views are initialized; view query results are ready. 8. `ngAfterViewChecked`: after the view is checked. Then, application-wide rather than per component, `afterNextRender` and `afterEveryRender` callbacks run once Angular has rendered **all** components to the DOM. At the end, `ngOnDestroy` runs once before the component is destroyed. ## Which hooks repeat | Hook | Runs | Typical use | |---|---|---| | `ngOnChanges` | first binding, then whenever a bound input gets a new value | react to specific input changes | | `ngOnInit` | once | initialisation that needs inputs | | `ngDoCheck` | every check | custom change checks (rarely needed) | | `ngAfterContentInit` | once | read content query results | | `ngAfterContentChecked` | every check | rarely needed | | `ngAfterViewInit` | once | read view query results | | `ngAfterViewChecked` | every check | rarely needed | | `ngOnDestroy` | once | cleanup | The per-check hooks run frequently and the docs advise avoiding them unless there is no alternative. One subtlety: `ngOnChanges`, `ngOnInit`, `ngDoCheck` and the content and view hooks of a child are invoked while Angular refreshes the **parent's** view, so they follow the parent being checked, not the child's own dirtiness. ## Parent and child interleaving For a parent whose template contains a child component, the first pass runs: - parent `ngOnChanges`, `ngOnInit`, `ngDoCheck`, `ngAfterContentInit`, `ngAfterContentChecked`; - then the parent's view is checked, which runs the child's entire sequence from `ngOnChanges` to `ngAfterViewChecked`; - then parent `ngAfterViewInit`, `ngAfterViewChecked`. So a parent's view hooks can rely on fully initialized children. Teardown goes the other way: Angular destroys the view tree from the bottom up, so nested children run their destroy hooks before the parent does. ## Directives and services follow the same hooks The class-method hooks are not only for components. A **directive** has the same sequence except that it has no template of its own, so its `ngAfterViewInit` and `ngAfterViewChecked` run once the view containing its host element, including any component on that element, has been initialized or checked. A **pipe** can implement `ngOnDestroy`. A **service** gets only `ngOnDestroy`, called when the injector that created it is destroyed. The render callbacks (`afterNextRender`, `afterEveryRender`) are different in kind: they are functions registered from an injection context rather than methods, and they belong to the application's render, not to one component's check. That is why the guide lists them in a separate "Rendering" phase after all change-detection hooks. ## Rules that follow from the order - **Do not change bound state in the after-content or after-view hooks.** Those bindings were already checked; in development mode Angular's verification pass detects the difference and throws `NG0100` (ExpressionChangedAfterItHasBeenCheckedError). - **Do not do DOM measurement in `ngAfterViewInit`.** It runs mid-walk and also during server rendering; `afterNextRender` runs after the DOM is complete and only in the browser. - **Do not rely on ordering between a component and the directives on the same element**, including `hostDirectives`: the docs say Angular does not guarantee the order of a given hook among them and warn that any observed order may change. - **Implement the interfaces** (`OnInit`, `AfterViewInit`, ...) so a misspelled hook name is a compile error rather than a method that silently never runs.
- With a parent and a child component, how do their hooks interleave on first render?The parent's `ngOnChanges`, `ngOnInit`, `ngDoCheck`, `ngAfterContentInit` and `ngAfterContentChecked` run first. Then Angular checks the parent's view, which runs the child's whole sequence through `ngAfterViewChecked`. Only then do the parent's `ngAfterViewInit` and `ngAfterViewChecked` run, so a parent's view hooks see fully initialized children.
- Why does updating a bound field in ngAfterViewInit raise an error in development?When `ngAfterViewInit` runs, Angular has already checked this component's view bindings. Changing a value they read leaves the checked view stale, and the development-mode verification pass throws `NG0100` (ExpressionChangedAfterItHasBeenCheckedError). Compute the value earlier, for example in `ngOnInit` or a `computed()`, or move DOM-only work to `afterNextRender`.
- Is the order of the same hook between a component and a directive on its host element guaranteed?No. Angular's docs state that it does not guarantee the order of a given lifecycle hook between a component and the directives on the same element, including those added with `hostDirectives`, and that an observed order may change in later versions. Coordinate through inputs, DI or signals instead.
saying these in an interview costs you the question
- ngOnInit runs before ngOnChanges on the first pass.
- ngAfterViewInit runs before ngAfterContentInit because the view is the component's own template.
- ngAfterViewInit and ngAfterContentInit run on every change detection pass.
- ngOnChanges always runs once, even when no input is bound.
- A parent's ngAfterViewInit runs before its child components have initialized.
- Hook order between a component and a directive on the same element is fixed.