Template Reference Variable In Angular
In this article, The Template Reference Variable in Angular is explained. We figure out what a template reference variable is and what it does. In Angular, how to define and use it.
Template Reference Variable
Any DOM element, component, or directive in the Template is referenced by the Template reference variable. It can be used in other parts of the template. We may also pass it to a component method. It can contain references to elements such as h1, div, and so on.
Defining Template Reference variable
# followed by the name of the variable (#variable) is used to declare Template reference variables. When the component/directive defines a customer as the exportAs Property, we can also declare them using #variable="customer."
For Example
HTML Element
<input type="text" #firstName>
Component/Directive
<app-customer #customerList=”customer”></app-customer>
Component/Directive with exportAs
<app-customer #customerList=”customer”></app-customer>
Template Reference variable Example
To learn how to use a template reference variable, let's develop a basic example application.
Create a new angular application using the following command:
ng new templateVariable
HTML Element
The #firstName and #lastName template reference variables are defined in the example code below. Both of them have a reference to the input HTML Element.
The value property is present in the input elements. As a result, as seen below, we can use it to display the welcome message.
Add the following code under the app.component.html:
<h1>{{title}}</h1> <p> <label for="firstName">First Name</label> <input (keyup)="0" type="text" #firstName id="firstName"> </p> <p> <label for="lastName">Last Name</label> <input (keyup)="0" type="text" #lastName id="lastName"> </p> <b>Welcome {{firstName.value}} {{lastName.value}} </b>
On the input element, we used (keyup)="0". It has no effect other than forcing the angular to conduct change detection. The view is updated as a result of the change detection.
When Angular runs the change detection, it refreshes the view. Only asynchronous events, such as the arrival of HTTP replies, the raising of events, and so on, trigger change detection. The keyup event is raised in the example above anytime you type in the input box. It forces angular to conduct change detection, resulting in the view receiving the most recent values.
Pass Variable to Component class
Variables can also be sent to the component as illustrated below.
Add the following code under the app.component.html:
<p> <button (click)="sayHello(firstName, lastName)"> Say Hello</button> </p>
Add the following code under the app.component.ts:
sayHello(firstName, lastName) { alert('Hello '+firstName.value+' '+ lastName.value) }
Component/Directive
A reference to the component or directive can be obtained. Refer to the Angular tutorial on Creating Child/Nested Components.
Create the customer-list.component.ts component and add the following code:
import { Component } from '@angular/core'; import { Customer } from './customer'; @Component({ selector: 'app-customer-list', templateUrl: './customer-list.component.html', exportAs:'customerList' }) export class CustomerListComponent { selectedCustomer customers: Customer[] = [ {customerNo: 1, name: 'Rahuld Dravid', address: '', city: 'Banglaore', state: 'Karnataka', country: 'India'}, {customerNo: 2, name: 'Sachin Tendulkar', address: '', city: 'Mumbai', state: 'Maharastra', country: 'India'}, {customerNo: 3, name: 'Saurrav Ganguly', address: '', city: 'Kolkata', state: 'West Bengal', country: 'India'}, {customerNo: 4, name: 'Mahendra Singh Dhoni', address: '', city: 'Ranchi', state: 'Bihar', country: 'India'}, {customerNo: 5, name: 'Virat Kohli', address: '', city: 'Delhi', state: 'Delhi', country: 'India'}, ] }
Put the following code under the customer-list.component.html:
<h2>List of Customers</h2> <table class='table'> <thead> <tr> <th>No</th> <th>Name</th> <th>Address</th> <th>City</th> <th>State</th> <th>Select</th> </tr> </thead> <tbody> <tr *ngFor="let customer of customers;"> <td>{{customer.customerNo}}</td> <td>{{customer.name}}</td> <td>{{customer.address}}</td> <td>{{customer.city}}</td> <td>{{customer.state}}</td> <button (click)="selectedCustomer=customer">Select</button> </tr> </tbody> </table>
Create a customer model namely as customer.ts:
export class Customer { customerNo: number; name:string ; address:string; city:string; state:string; country:string; }
Add the following code under the app.component.html:
You have selected {{customerListComponent.selectedCustomer?.name}} <app-customer-list #customerListComponent></app-customer-list>
ExportAs
There may be several directives on a DOM Element at any same moment.
The following code, for example, has two directives. In this situation, we must specify the #variable directive to use.
<a-directive b-directive #variable />
ExportAs can be used by components or directives to export the component or directive under an alternative name.
Open the customer-list.component, for example, and add the exportAs:'customerList' metadata to the @Component metadata.
@Component({ selector: 'app-customer-list', templateUrl: './customer-list.component.html', exportAs:'customerList' })
You can now use it in a variety of ways.
You have selected {{customerList.selectedCustomer?.name}} <app-customer-list #customerList="customerList"></app-customer-list>
The safe navigation operator ( ? )
When the app first launches, the selectedCustomer is null. Only when the user presses the select button does it obtain its value. To guard against null or undefined values, we use? or a safe navigation operator.
What if there was no? The app will crash and throw an error.
Template Driven Forms
The exportAs function is used by the ngForm directive to export an instance of itself with the name ngForm. This is used in Angular's template-driven forms.
<form #contactForm="ngForm" (ngSubmit)="onSubmit(contactForm)">
Within the template, you can now examine the form's value and validate its status.
<pre>Value : {{contactForm.value | json }} </pre> <pre>Valid : {{contactForm.valid}} </pre> <pre>Touched : {{contactForm.touched }} </pre> <pre>Submitted : {{contactForm.submitted }} </pre>
Template Input Variable
The Template input variable, which we define using the let keyword in the template, should not be confused with the Template reference variable.
Check out the ngFor loop in the customer-list.component.html for an example. The customer variable is a template input variable.
<tr *ngFor="let customer of customers;"> <td>{{customer.customerNo}}</td> <td>{{customer.name}}</td> <td>{{customer.address}}</td> <td>{{customer.city}}</td> <td>{{customer.state}}</td> <button (click)="selectedCustomer=customer">Select</button> </tr>
Variable Scope
The template reference variable's scope is limited to the template in which it is declared. You can't get to it unless you're inside the template.
As a result, any variable declared in CustomerListComponent cannot be accessed from the app component, despite the fact that the app component renders the customer list.
Child scope
Also, the directive ng-template can be used to construct a new child template scope (nested scope). In addition, structural directives such as ngIf, ngFor, and others construct their own child scope.
The <ng-template> directive is demonstrated in the following example. Outside of the ng-template, the address variable is not accessible.
<h2>Variable Scope</h2> <div *ngIf="false else addressTemplate"></div> <ng-template #addressTemplate> <p> <label for="address">Address</label> <input (keyup)="0" type="text" #address id="address"> </p> <p>The address of {{firstName.value}} {{lastName.value}} Entered {{address.value}} </p> </ng-template> <!-- address is not accessible here --> <p> You Entered {{address?.value}} </p>
ngIf Example
<div *ngIf="true"> <app-customer-list #variable></app-customer-list //variable is accessible from here </div>
//variable is not accessible from here
Conclusion
Any DOM element, component, or directive in the Template is referenced by the Template reference variable. To make a reference to it, type #variable. When the component/directive defines an exportAs metadata, we can also use #variable="exportAsName". Anywhere in the template, the template variable can be used. The variable can be provided to a method as an argument by the component. The Template reference variable is distinct from the template input variable, which is defined within the template using the let keyword. They're limited to Templates. If you expect a null value, you can also use the safe navigation operator(?)
I hope this article helps you and you will like it.👍
If you have any doubt or confusion then free to ask in the comment section.