A component in Angular has a life-cycle, a number of different phases it goes through from birth to death. We can hook into those different phases to get some pretty fine grained control of our application. To do this we add some specific methods to our component class which get called during each of these life-cycle phases, we call those methods hooks.
Angular creates it, renders it, creates and renders its children, checks it when its data-bound properties change, and destroys it before removing it from the DOM. Angular offers lifecycle hooks that provide visibility into these key life moments and the ability to act when they occur. A directive has the same set of lifecycle hooks, minus the hooks that are specific to component content and views.
These phases are broadly split up into phases that are linked to the component itself and phases that are linked to the children of that component.
Hooks for the component
- constructor – This is invoked when Angular creates a component or directive by calling new on the class.
- ngOnChanges – Invoked every time there is a change in one of th input properties of the component.
- ngOnInit – Invoked when given component has been initialized. This hook is only called once after the first ngOnChanges
- ngDoCheck – Invoked when the change detector of the given component is invoked. It allows us to implement our own change detection algorithm for the given component.
- ngDoCheck and ngOnChanges should not be implemented together on the same component.
Component lifecycle hooks
Directive and component instances have a lifecycle as Angular creates, updates, and destroys them. Developers can tap into key moments in that lifecycle by implementing one or more of the lifecycle hook interfaces in the Angular core library.
Each interface has a single hook method whose name is the interface name prefixed with ng. For example, the OnInit interface has a hook method named ngOnInit() that Angular calls shortly after creating the component:
peek-a-boo.component.ts (excerpt)
export class PeekABoo implements OnInit {
constructor(private logger: LoggerService) { }
// implement OnInit’s `ngOnInit` method
ngOnInit() { this.logIt(`OnInit`); }
logIt(msg: string) {
this.logger.log(`#${nextId++} ${msg}`);
}
}
No directive or component will implement all of the lifecycle hooks and some of the hooks only make sense for components. Angular only calls a directive/component hook method if it is defined.
Lifecycle sequence
After creating a component/directive by calling its constructor, Angular calls the lifecycle hook methods in the following sequence at specific moments:
Hook | Purpose and Timing |
ngOnChanges() | Respond when Angular (re)sets data-bound input properties. The method receives a SimpleChanges object of current and previous property values. Called before ngOnInit() and whenever one or more data-bound input properties change. |
ngOnInit() | Initialize the directive/component after Angular first displays the data-bound properties and sets the directive/component’s input properties. Called once, after the first ngOnChanges(). |
ngDoCheck() | Detect and act upon changes that Angular can’t or won’t detect on its own. Called during every change detection run, immediately after ngOnChanges() and ngOnInit(). |
ngAfterContentInit() | Respond after Angular projects external content into the component’s view / the view that a directive is in. Called once after the first ngDoCheck(). |
ngAfterContentChecked() | Respond after Angular checks the content projected into the directive/component. Called after the ngAfterContentInit() and every subsequent ngDoCheck(). |
ngAfterViewInit() | Respond after Angular initializes the component’s views and child views / the view that a directive is in. Called once after the first ngAfterContentChecked(). |
ngAfterViewChecked() | Respond after Angular checks the component’s views and child views / the view that a directive is in. Called after the ngAfterViewInit and every subsequent ngAfterContentChecked(). |
ngOnDestroy() | Cleanup just before Angular destroys the directive/component. Unsubscribe Observables and detach event handlers to avoid memory leaks. Called just before Angular destroys the directive/component. |
Hooks for the components children
These hooks are only called for components and not directives.
- ngAfterContentInit – Invoked after Angular performs any content projection into the components view.
- ngAfterContentChecked – Invoked each time the content of the given component has been checked by the change detection mechanism of Angular.
- ngAfterViewInit – Invoked when the component’s view has been fully initialized.
- ngAfterViewChecked – Invoked each time the view of the given component has been checked by the change detection mechanism of Angular.
Adding hooks
In order to demonstrate how the hooks work we’ll adjust the joke application we’ve been working with so far. Firstly lets change the JokeComponent so it hooks into all the phases. All we need to do is to add functions to the component class matching the hook names above, like so:
class JokeComponent {
@Input(‘joke’) data: Joke;
constructor() {
console.log(`new – data is ${this.data}`);
}
ngOnChanges() {
console.log(`ngOnChanges – data is ${this.data}`);
}
ngOnInit() {
console.log(`ngOnInit – data is ${this.data}`);
}
ngDoCheck() {
console.log(“ngDoCheck”)
}
ngAfterContentInit() {
console.log(“ngAfterContentInit”);
}
ngAfterContentChecked() {
console.log(“ngAfterContentChecked”);
}
ngAfterViewInit() {
console.log(“ngAfterViewInit”);
}
ngAfterViewChecked() {
console.log(“ngAfterViewChecked”);
}
ngOnDestroy() {
console.log(“ngOnDestroy”);
}
}