Angular: Understanding Life cycle hooks/events

Learn about the life cycle events of angular and their uses in components.

Lifecycle hooks are nothing but the events that happen in life cycle of a component or a directive to instantiate a component instance, initialize its property, detect the changes in DOM, run the change detection and clean up before destroying the component.

There are 8 life cycle hooks in angular which handles the life cycle of Angular components and directives.

Along with these 8 lifecycle hooks, we can use constructor ( provided by ES6 & Typescript ) to initialize the properties and also gets called whenever a new instance of component gets created.

Note: constructor is not a life cycle event and not provided by Angular.

Here is the list of life cycle events ( in order of their execution )we get from Angular.

  1. ngOnChanges()
  2. ngOnInit()
  3. ngDoCheck()
  4. ngAfterContentInit()
  5. ngAfterContentChecked()
  6. ngAfterViewInit()
  7. ngAfterViewChecked()
  8. ngOnDestroy()

Note: These above events are declared in their respective interfaces provided by Angular. To hook the events and run your custom implementation, then you must “implements” the interface and then you must provide the implementation to the life cycle method you want to use.

we can further categorize these events into two categories -

  1. Hooks for Components and Directives
  2. Hooks for Component’s children component

Events for Components and Directives events in their execution order -

  1. ngOnChanges()
  2. ngOnInit()
  3. ngDoCheck()
  4. ngOnDestroy()

Events for Component’s Children Component -

  1. ngAfterContentInit()
  2. ngAfterContentChecked()
  3. ngAfterViewInit()
  4. ngAfterViewChecked()

Let’s learn about each event in detail -

we will first learn the use of constructor and then will move to life cycle hooks as constructor plays a major role in any component and service.

Constructors: —

constructors are identified with keyword “constructor”. Class constructors are very similar to functions but with few differences -

  1. Constructors can not have any return type. Basically these are used to get the instance of the class.
  2. Constructors are used to inject the dependency to the class or component.
  3. Constructors are the best place to initialize the properties of the component or a class.
  4. Constructors can be overloaded ( meaning more than one constructor but their signature will be different in terms of the parameter passed to it ).
  5. when a component gets instantiated, the constructor gets called even before the angular life cycle events.

example -

Use of Constructor in Service
Use of Constructor in Service
Constructor in Service

Note: Injecting dependencies meaning if your component or a service has dependency of other service or injectable module, you can pass those instances to constructor as parameter and at the time of class instantiation, those services/dependencies will get injected to the class/component/service.

Usage of Life Cycle events -

  1. ngOnChanges(): This event comes from the OnChanges interface. If you want to use/hook this event in your component, you must have to implement the interface “OnChanges”.

This life cycle method gets called first( even before the “ngOnInit”). It gets called only when your component has any data-bound input properties ( meaning any property declared with @input() decorator ).

It will not be called if there is no input property present in the component. This method will be called each time whenever there is change in the input property.

This method accepts the parameter SimpleChanges which has the current and previous values of the property and then you can assign the latest value to the input property.

2. ngOnInit(): This event comes from the OnInit interface. If you want to use/hook this event in your component, you must have to implement the interface “OnInit”.

This method gets called once after the first “ngOnChanges()” is called. It will be always called even if ngOnChanges() not called ( when there is no input property in component ).

It Initialize the directive or component after the Angular first displays the input bound properties. This is the default behavior. You can customize the method to perform the complex logic. “ngOnInit ”is the best place when you want to fetch the initial data from the server or want to make the api calls.

Note : ngOnInit gets called only once in the life time of the component.

According the angular documentation:

ngDoCheck method detects and acts upon changes that Angular can’t or won’t detect on its own. It is called during every change detection run, immediately after ngOnChanges() and ngOnInit()

Basically whenever your input property changes, Angular runs ngOnChanges() method to detect the change and gets the latest value but if you are using the ChangeDetectionStrategy.onPush and you are updatin the @input reference’s property but your input property reference is not changing that time Angular does not run ngOnChanges and it does not detect the change. In such scenario, we are required to use ngDoCheck so Angular will detect the change in the input reference and you will get the latest value.

Let’s understand this through an example -

Child Component implemented ngDoCheck()
Child Component implemented ngDoCheck()
Parent component updating the input property

Let’s understand the example. Here in ChildComponent we have one input property “user” and it is using “OnPush” change detection strategy. Inside the template of child component, it is using “name” property of “user”.

We have ParentComponent that passes the “user” value to the child Component’s “user”. Inside the ngOnInit, after 2 seconds, it mutates the object by updating the “id” and “name” properties.

since angular tracks the object reference and we are mutating the object without changing its reference, Angular will not detect the changes and it will not run the change detection for ChildComponent thus the “name” property will not render in Child’s DOM.

So here in “childComponent”, we have implemented ngDoCheck() life cycle hook to check for object mutation and notify angular using “markForCheck” method. It will check if the object has been changed, you can get the latest value and will run the change detection.

4. ngAfterContentInit(): This life cycle method gets invoked when Angular projects external content into Component’s view ( using ng-content or @contentChildern / @contentChild decorator ).

It waits for “@contentChild()” query to finishes the rendering in DOM.

“@contentChild() query results are not available before the ngAfterContentInit() life cycle.”

Note: This method get called once after the first ngDoCheck() is called.

5. ngAfterContentChecked() : This life cycle method get invoked when Angular checks the content projection into the view of Component or Directive. Meaning as soon as projected content ( using ng-content ) finishes the rendering, this life cycle hook fires.

whenever the content of the given component or directive is checked by change detection mechanism of Angular.

ngAfterContentChecked()” can be invoked frequently and can cause performance issues if poorly implemented.

Whenever angular is doing change detection at component level, one of the thing is to check the content part for changes.

<parent-component>

<child-component [src]=”imagePath”></child-component>

</parent-component>

In above example, it checks if the value of the image path is changed since the last time change detection was executed.

After performing this content check, Angular is going to execute the “ngAfterContentChecked()” event. This life cycle event is going to be called with every event that Angular is handling.

For example — whenever you click on a button or you get the request data from API calls, this method will get called whenever angular run change detection cycle.

Since this method is going to called for several times so you have to be very careful while implementing this method. You should avoid writing expensive logic / calculation inside this event so that it will not impact the performance.

you can write simple logic that you want to execute after every change detection.

Let’s suppose if the property of content part changes( image path in our example ) inside this method then it will throw below error -

ExpressionChangedAfterItHasBeenCheckedError : Expression changed after it was checked, Previous value: “imageUrl”, currentValue: “” (blank)

To know more about this error. please click here.

https://garghimanshu.medium.com/explained-expressionchangedafterithasbeencheckederror-c798b0563dc2

Note: This method gets called after ngAfterContentInit and every subsequent ngDoCheck().

6. ngAfterViewInit(): This method fires once the view DOM finishes the initializing. It responds when Angular initializes the component’s view, its child’s view or the view that contains any directive.

The view always loads after the content and this method waits on @viewChild() Query to resolve.

“@ViewChild() query results are not available before ngAfterViewInit unless the “static” option is set as true in ViewChild().

Note: This method called once after the first ngAfterContentChecked()

7. ngAfterViewChecked() : This life cycle event gets invoked after the “ngAfterViewInit()” when Angular checks that view is initialised in component of directive.

It gets called after all the child components are initialized and checked. It is executed every time the when the view of the given component has been checked by the change detection algorithm of Angular.

8. ngOnDestroy() : This is the last and final life cycle event of Angular which gets called whenever the Angular Component gets destroyed or user leaves the component (navigation to another page).

This method is the perfect place to write the code to Unsubscribe all the active observable subscriptions or to close any database connection so that when component gets destroyed you are not leaving any subscription or connection open and to ensure there is no memory leaks.

It gets called only once just before the component is removed from the DOM (when displaying component using *ngIf and when condition is false, it removes the component from DOM).

I am an Angular Developer having 8+ years of experience in IT. I am currently working with Cognizant Technologies, India. https://www.garghimanshu.com