Important Update
The Guide Feature will be discontinued after December 15th, 2023. Until then, you can continue to access and refer to the existing guides.
Author avatar

Gaurav Singhal

Using Template Reference Variables to Interact with Nested Components

Gaurav Singhal

  • Dec 19, 2019
  • 5 Min read
  • 14,703 Views
  • Dec 19, 2019
  • 5 Min read
  • 14,703 Views
Languages Frameworks and Tools
Angular

Introduction

Hello friends! In this guide, we're going to learn about template reference.

There are multiple ways to interact between components, such as @Input and @Output. But what if we have to call the child function in the parent component?

In this scenario, we could create a new function in the parent component, or we could create a service file with a common function and use it in the parent and child function.

Today we'll learn another method known as template reference so you can avoid creating a different function in the parent component or a different service file.

Creating Components

We need to create two components: a child component and a parent component. It is a good practice to have a different folder for each file. So I'm going to create all the components in components folder.

1ng g c /components/parent --skipTests=true
console
1ng g c /components/child --skipTests=true
console

In the above snippet, I've used the short form of the generate, or g, and the short form of the component,or c. Notice that --skipTests=true, lthough we're not going to write and unit test case, so I've used that to skip the file of the testing.

So we are ready to go. Let's get dive into template reference.

Make Function in Child Component

Now it's time to make a function in the child component so we can call it in the parent component by using the reference of the child component.

child.component.ts

1import { Component, OnInit } from '@angular/core';
2
3@Component({
4  selector: 'app-child',
5  templateUrl: './child.component.html',
6  styleUrls: ['./child.component.scss']
7})
8export class ChildComponent implements OnInit {
9
10  constructor() { }
11
12  ngOnInit() {
13  }
14
15  hello(){
16    console.log('hello from child component');
17  }
18
19}
ts

I've made a hello() function. Once the function is called, we'll get a message on the console.

Get Reference of Child Component

We've successfully made a function in the child component. Now it's time to put the child component in the parent component.

parent.component.html

1<app-child #child></app-child>
html

Noticed that I've written #child under the tag of app-child. In Angular, to refer to any component, we need to put # with a string. I've written #child in our case so we can use it to get the reference of the child component.

Use of @ViewChild Decorator

The @ViewChild() decorator is one of the most useful decorators in Angular. It is used to get the reference of the component. The syntax of @ViewChild() is :

1@ViewChild('referenceVariable') childVariable:ChildComponent
console

It accepts a reference variable, which is #child in our case. We've written this in the parent component under the child tag. childVariable can be anything—it's just a variable name that we will use to access a variable or function of the child component. To make a typed secure, we should always write the type of the variable by using a colon (:).

Use of ngAfterViewInit() Angular Lifecycle Hooks

ngAfterViewInit is one of the Angular lifecycle hooks. We can use the @ViewChild variable into it. We can't access the @ViewChild variable in ngOnInit, ngOnChanges, or ngDoCheck because it can be accessed only after our view is initialized.

Call Child Function in Parent Component

parent.component.ts

1import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
2import { ChildComponent } from '../child/child.component';
3
4@Component({
5  selector: 'app-parent',
6  templateUrl: './parent.component.html',
7  styleUrls: ['./parent.component.scss']
8})
9export class ParentComponent implements OnInit {
10
11  @ViewChild('child') child: ChildComponent;
12  
13  constructor() { }
14
15  ngOnInit() {
16  }
17
18  ngAfterViewInit(){
19    this.child.hello();
20  }
21
22}
ts

In the above snippet, we've used the @ViewChild decorator to get the reference of the child element. We used the child element reference variable I've called hello() function in ngAfterViewInit(), which we've defined in the child component.

Output:

1hello from child component
console

You'll get the same output at the console.

Conclusion

Template reference is one of the best ways to minimize code. It saves a line of code and gives you the same result with minimum time. Lines of code do matter if you talk about productivity.

You can read more about template reference here.