Author avatar

Gaurav Singhal

Using Lifecycle Hooks

Gaurav Singhal

  • Nov 25, 2019
  • 10 Min read
  • 35 Views
  • Nov 25, 2019
  • 10 Min read
  • 35 Views
Web Development
Angular

Introduction

In this guide, we'll learn about Angular lifecycle hooks.

Lifecycle hooks are essential in any JavaScript framework. All components have lifecycle hooks managed by Angular. Angular creates the hooks, renders them, creates and renders their children, checks when data-bound properties change, and destroys them before removing them from the DOM. We'll talk more about these lifecycle hooks, which demonstrate each state of the life of the component or directive.

Lifecycle Hooks

Directive and component instances have a life cycle as Angular creates, updates, and destroys them. Developers can tap into critical moments in that life cycle 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. Here's a list of lifecycle hook methods in the order in which Angular calls them.

  • ngOnChanges()
  • ngOnInit()
  • ngDoCheck()
  • ngAfterContentInit()
  • ngAfterContentChecked()
  • ngAfterViewInit()
  • ngAfterViewChecked()
  • ngOnDestroy()

Adding interfaces is optional since interfaces are removed from the transpiled JavaScript.

However, it is a good practice to add them when using the lifecycle hook methods. Lifecycle hooks are called after the constructor.

ngOnChanges()

This hook gets called after a data-bound input property is set or reset. It detects the changes in data-bound automatically and sets the variable with updated data.

ngOnInit()

This hook initializes the component. In this function, we usually write the method that we want to get executed before our data renders on the screen, and it gets called after the ngOnChanges() method.

ngDoCheck()

This hook detects and acts upon every change that Angular can't find automatically. It gets called before ngOnChanges() and ngOnInit() methods.

ngAfterContentInit()

This hook initializes the external component and projects it into the current component. It gets called after ngDoCheck() method. It is called once for the first time.

ngAfterContentChecked()

This hook gets called after the external component is projected into the current component and whenever there is a change in the external component. It is called after ngDoCheck() and ngAfterContentInit().

ngAfterViewInit()

This hook initializes the view of the component and is called once for the first time. It gets called after ngAfterContentChecked().

ngAfterViewChecked()

This hook gets called after the content and the child component view gets in and is called after ngAfterViewInit() and ngAfterContentChecked() whenever the content is being changed.

ngOnDestroy()

This hook gets called before the component is getting off the DOM. Unsubscribe every subscription and clear every interval to prevent memory leaks.

You can learn more about angular lifecycle hooks here.

So that's the theory section. Now let's dive into the code to give you a clearer view.

Practical Implementation

First, we need a project, so let's create it with the following code :

1
ng new demo
console

Now let's create the child component.

1
ng g c child
console

Now we're ready to implement the example. We'll implement the lifecycle hooks in both components and add a data-bound to the child component.

app.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
export class AppComponent
  implements
    OnChanges,
    OnInit,
    AfterContentInit,
    AfterContentChecked,
    AfterViewInit,
    AfterViewChecked,
    OnDestroy {
  parentData: any;
  data: string;

  ngOnChanges(changes: SimpleChanges): void {
    console.log("this is the parent onChanges method");
  }
  ngOnInit(): void {
    console.log("this is the parent on init method");
    this.data = "This is the parent";
  }

  ngDoCheck(): void {
    console.log("this is the parent onDoCheck method");
  }

  ngAfterContentInit(): void {
    console.log("this is the parent ngAfterContentInit method");
  }
  ngAfterContentChecked(): void {
    console.log("this is the parent ngAfterContentChecked method");
  }
  ngAfterViewInit(): void {
    console.log("this is the parent ngAfterViewInit method");
  }
  ngAfterViewChecked(): void {
    console.log("this is the parent ngAfterViewChecked method");
  }
  ngOnDestroy(): void {
    console.log("this is the parent onDestroy method");
  }
}
ts

app.component.ts will work as the parent component. So we have defined two variables — one to detect the change and one to perform the data-bound in the child component.

app.component.html

1
2
3
4
5
6
7
8
9
<app-child [parentData]="data"></app-child>
<input
  type="text"
  name="test"
  id="test"
  placeholder="test"
  [(ngModel)]="parentData"
/>
{{parentData}}
html

In this app.component.html, we have implemented the app-child component with the data-bound property and input tag with two-way data binding, which will change the parentData .

child.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
export class ChildComponent
  implements
    OnChanges,
    OnInit,
    AfterContentInit,
    AfterContentChecked,
    AfterViewInit,
    AfterViewChecked,
    OnDestroy {
  @Input() parentData;

  constructor() {}

  ngOnChanges(changes: SimpleChanges): void {
    console.log("this is the child onChanges method");
  }
  ngOnInit(): void {
    console.log("this is the child on init method");
  }

  ngDoCheck(): void {
    console.log("this is the child onDoCheck method");
  }
  ngAfterContentInit(): void {
    console.log("this is the child ngAfterContentInit method");
  }
  ngAfterContentChecked(): void {
    console.log("this is the child ngAfterContentChecked method");
  }
  ngAfterViewInit(): void {
    console.log("this is the child ngAfterViewInit method");
  }
  ngAfterViewChecked(): void {
    console.log("this is the child ngAfterViewChecked method");
  }
  ngOnDestroy(): void {
    console.log("this is the child onDestroy method");
  }
}
ts

In this child.component.ts, we implemented the lifecycle hooks with a @Input(), which is required to data-bound.

child.component.html

1
This is the child component
html

In child.component.html, we are just displaying a message to indicate that this is child component data.

Now we're ready to run the project, and output will display in the console. Run it with the below command:

1
ng serve
console

Output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 this is the parent on init method                          app.component.ts:22
 this is the parent onDoCheck method                        app.component.ts:27 
 this is the parent ngAfterContentInit method               app.component.ts:31
 this is the parent ngAfterContentChecked method            app.component.ts:34
 this is the child onChanges method                         child.component.ts:15
 this is the child on init method                           child.component.ts:18
 this is the child onDoCheck method                         child.component.ts:22
 this is the child ngAfterContentInit method                child.component.ts:25
 this is the child ngAfterContentChecked method             child.component.ts:28
 this is the child ngAfterViewInit method                   child.component.ts:31
 this is the child ngAfterViewChecked method                child.component.ts:34
 this is the parent ngAfterViewInit method                  app.component.ts:37
 this is the parent ngAfterViewChecked method               app.component.ts:40
 this is the parent onDoCheck method                        app.component.ts:27
 this is the parent ngAfterContentChecked method            app.component.ts:34
 this is the child onDoCheck method                         child.component.ts:22
 this is the child ngAfterContentChecked method             child.component.ts:28
 this is the child ngAfterViewChecked method                child.component.ts:34
 this is the parent ngAfterViewChecked method               app.component.ts:40
console

Here you will notice some key behaviors of the lifecycle hook methods.

As we discussed above, first of all, the ngOnChanges() method would act. But there is the condition that it should have a data-bound input property. In our app.component.html, there is no @Input() present; therefore, in this case, it gets executed directly after the ngOnInit() method. After ngOnInit(), it runs the ngDoCheck() method to check the changes in the component. Then it initializes the content of the component with the help of ngAfterContentInit(), then checks whether the component was loaded successfully in the component. Finally, it hits the ngAfterContentChecked() method.

Now Content is loaded, and our child component is ready to hit its lifecycle hooks. But there is a change between our app and the child component. In the child component, we have the @Input() method, so it hits the ngOnChanges() method first and gets the change in the instance of SimpleChanges interface. Then it goes through the entire lifecycle, as we went through in App component.

After all content is loaded successfully in the parent component in our case, it is an app component. It's time to view them. It hits the ngAfterViewInit() method to initialize the view of the component, and after the view is done it will run the ngAfterViewChecked(). After that, when you make any changes, it will hit the ngDoCheck() method to detect the changes, add all the changes in the DOM, and render it on the screen.

ngOnDestroy() hits before the component is getting off the DOM.

Conclusion

Every framework, such as ReactJs or Angular, has lifecycle hook methods. Lifecycle hooks play a significant role when you're making a website using these frameworks by giving you more control over frameworks.

0