angular / 13.3.8 / guide / template-reference-variables.html /

Template variables

Template variables help you use data from one part of a template in another part of the template. Use template variables to perform tasks such as respond to user input or finely tune your application's forms.

A template variable can refer to the following:

See the live example for a working example containing the code snippets in this guide.

Syntax

In the template, you use the hash (#) character to declare a template variable. The following template variable, #phone, declares a phone variable on an <input> element.

<input #phone placeholder="phone number" />

Refer to a template variable anywhere in the component's template. Here, a <button> further down the template refers to the phone variable.

<input #phone placeholder="phone number" />

<!-- lots of other elements -->

<!-- phone refers to the input element; pass its `value` to an event handler -->
<button type="button" (click)="callPhone(phone.value)">Call</button>

How Angular assigns values to template variables

Angular assigns a template variable a value based on where you declare the variable:

  • If you declare the variable on a component, the variable refers to the component instance

  • If you declare the variable on a standard HTML tag, the variable refers to the element

  • If you declare the variable on an <ng-template> element, the variable refers to a TemplateRef instance, which represents the template. For more information on <ng-template>, see How Angular uses the asterisk, *, syntax in Structural directives.

  • If the variable specifies a name on the right-hand side, such as #var="ngModel", the variable refers to the directive or component on the element with a matching exportAs name.

Using NgForm with template variables

In most cases, Angular sets the template variable's value to the element on which it occurs. In the previous example, phone refers to the phone number <input>. The button's click handler passes the <input> value to the component's callPhone() method.

The NgForm directive is applied by Angular on <form> elements. This example demonstrates getting a reference to a different value by referencing a directive's exportAs name.

<form #itemForm="ngForm" (ngSubmit)="onSubmit(itemForm)">
  <label for="name">Name</label>
  <input type="text" id="name" class="form-control" name="name" ngModel required />
  <button type="submit">Submit</button>
</form>

<div [hidden]="!itemForm.form.valid">
  <p>{{ submitMessage }}</p>
</div>

Without the ngForm attribute value, the reference value of itemForm would be the HTMLFormElement, <form>.

With NgForm, itemForm is a reference to the NgForm directive with the ability to track the value and validity of every control in the form.

Unlike the native <form> element, the NgForm directive has a form property. The NgForm form property lets you disable the submit button if the itemForm.form.valid is invalid.

Default reference type without assigned value

When declaring a template reference variable on an element without defining a value for it, its returned type will reflect the type of element it's applied to:

  • Native element: specific subclass of HTMLElement
  • Component: instance of the specific Component class
  • NgTemplate: TemplateRef

Referencing an element by its directive needs the directive exportAs property set as reference value. In case of an unspecified variable value, the reference will return an HTMLElement, even if the element has one or more directive applied to itself.

Template variable scope

Refer to a template variable anywhere within its surrounding template. Structural directives, such as *ngIf and *ngFor, or <ng-template> act as a template boundary. You cannot access template variables outside of these boundaries.

Define a variable only once in the template so the runtime value remains predictable.

Accessing in a nested template

An inner template can access template variables that the outer template defines.

In the following example, changing the text in the <input> changes the value in the <span> because Angular immediately updates changes through the template variable, ref1.

<input #ref1 type="text" [(ngModel)]="firstExample" />
<span *ngIf="true">Value: {{ ref1.value }}</span>

In this case, there is an implied <ng-template> around the <span> and the definition of the variable is outside of it. Accessing a template variable from the parent template works because the child template inherits the context from the parent template.

Rewriting the preceding code in a more verbose form explicitly shows the <ng-template>.

<input #ref1 type="text" [(ngModel)]="firstExample" />

<!-- New template -->
<ng-template [ngIf]="true">
  <!-- Because the context is inherited, the value is available to the new template -->
  <span>Value: {{ ref1.value }}</span>
</ng-template>

However, accessing a template variable from outside the parent template doesn't work.

<input *ngIf="true" #ref2 type="text" [(ngModel)]="secondExample" />
<span>Value: {{ ref2?.value }}</span> <!-- doesn't work -->

The verbose form shows that ref2 is outside the parent template.

<ng-template [ngIf]="true">
  <!-- The reference is defined within a template -->
  <input #ref2 type="text" [(ngModel)]="secondExample" />
</ng-template>
<!-- ref2 accessed from outside that template doesn't work -->
<span>Value: {{ ref2?.value }}</span>

Consider the following example that uses *ngFor.

<ng-container *ngFor="let i of [1,2]">
  <input #ref type="text" [value]="i" />
</ng-container>
{{ ref.value }}

Here, ref.value doesn't work. Verbose syntax of the same loop shows why:

<ng-template ngFor let-i [ngForOf]="[1,2]">
  <input #ref type="text" [value]="i" />
</ng-template>
{{ ref.value }}

The interpolation trying to access property ref.value occurs outside of the referenced element's parent template, making it unreachable.

Moving the interpolation inside the template makes the variable available. Now it references the correct distinct value for each element the loop renders.

<ng-template ngFor let-i [ngForOf]="[1,2]">
  <input #ref type="text" [value]="i" />
  {{ ref.value }}
</ng-template>

This snippet shows 2 <input> elements, with their respective value printed.

Accessing a template variable within <ng-template>

When you declare the variable on an <ng-template>, the variable refers to a TemplateRef instance, which represents the template.

<ng-template #ref3></ng-template>
<button type="button" (click)="log(ref3)">Log type of #ref</button>

In this example, clicking the button calls the log() function, which outputs the value of #ref3 to the console. Because the #ref variable is on an <ng-template>, the value is TemplateRef.

The following is the expanded browser console output of the TemplateRef() function with the name of TemplateRef.

▾ ƒ TemplateRef()
name: "TemplateRef"
__proto__: Function

Template input variable

A template input variable is a variable to reference within a single instance of the template. You declare a template input variable using the let keyword as in let hero.

If its value is omitted, it gets the $implicit template context's property value.

There are several such variables in this example: hero, i, and odd. The first one takes the value of the iterated item, because NgForOf assigns that to $implicit

<ng-template ngFor #hero let-hero [ngForOf]="heroes" let-i="index" let-odd="odd">
  <div [class]="{'odd-row': odd}">{{i}}:{{hero.name}}</div>
</ng-template>

The variable's scope is limited to a single instance of the repeated template. Use the same variable name again in the definition of other structural directives.

When in the same template a template reference variable and a template input variable with the same name get declared, the latter takes precedence.

© 2010–2022 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://v13.angular.io/guide/template-reference-variables