Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Angular templates support two distinct variable forms: use @let to name the current value of an expression, and use #name to reference an element, component, directive, or template. Both are limited by template scope, so a variable declared inside a block cannot be used by its parent template.

Choose the right Angular template variable

Form What it does What the variable refers to
@let name = expression; Names an expression value for reuse; Angular keeps it current as the expression changes. The value of the expression.
#name Creates a reference to the object represented by its host. Usually a DOM element; on a component, the component instance; on an <ng-template>, a TemplateRef. It can refer to a directive instance when the directive is explicitly selected through its exportAs name.

These are Angular’s two template variable declaration types, but they solve different problems: @let gives an expression a local name, while #name identifies a template object. See Angular’s variables guide.

Declare a local variable with @let

Use @let when you want to refer to an expression result more than once in a template. The declaration uses the keyword, a valid JavaScript identifier, an equals sign, an Angular expression, and a semicolon. It declares exactly one variable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
@let user = user$ | async;

@if (user) {
  <h1>Hello, {{ user.name }}</h1>
  <button (click)="update(user)">Update profile</button>
}

Angular updates the variable as its expression changes, but the variable is not assignable. Treat it as an expression-backed binding, not a mutable JavaScript local. The expression can span multiple lines, but the declaration still ends with a semicolon.

Create a template reference with #name

Place a reference name on the element or template you want to identify. The referenced value depends on the host:

  • On a regular HTML element, it refers to the element.
  • On a component, it refers to the component instance.
  • On an <ng-template>, it refers to a TemplateRef.
  • On an element with an exported directive, it can refer to that directive instance.
<input #taskInput placeholder="Enter task name" />

To select a directive instance, provide the directive’s exportAs name. For example, this syntax works only if the directive declares exportAs: 'dropZone':

<section dropZone #firstZone="dropZone">...</section>

A directive without a matching exportAs name cannot be referenced this way. Template references can also be used by component queries such as @ViewChild('description'); the Angular guide explains template reference variables and queries.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Understand template scope

Variables are available in the template where they are declared and in nested scopes inside it. A nested scope can read an outer variable, but a parent template cannot reach into a child scope. @let declarations are not hoisted, so declare a variable where it is available before using it.

@let topLevel = value;

@if (condition) {
  {{ topLevel }}
  @let nested = value;
  {{ nested }}
}

<!-- `nested` is unavailable here: it belongs to the @if scope. -->

The same rule applies to variables declared within @for, structural directives, and <ng-template> scopes. If a value is needed outside a block, declare it in an enclosing scope where it is available.

Distinguish @let from let- template parameters

An @let declaration names an expression in the current template. A let- attribute on <ng-template> instead declares a parameter that receives a value from that template fragment’s context object.

<ng-template #fragment let-topping="topping">
  <p>You selected: {{ topping }}</p>
</ng-template>

<ng-container
  [ngTemplateOutlet]="fragment"
  [ngTemplateOutletContext]="{ topping: 'onion' }" />

Here, topping gets its value from the outlet context. The fragment remains associated with the component in which it was declared. See Angular’s guide to template fragments and context.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Handle names that shadow component members

Template expressions can access the component context as well as template variables and other locals. When a local variable and a component member have the same name, the local variable takes precedence. Use this.member when you need to refer explicitly to the component member; Angular documents this behavior in its expression syntax guide.

Common mistakes to avoid

  • Trying to assign a new value to a variable declared with @let.
  • Using a variable outside the block or template scope where it was declared.
  • Assuming every #name refers to a DOM element, even when it is attached to a component or <ng-template>.
  • Using #directive="name" without a matching directive exportAs value.
  • Treating let- context parameters as interchangeable with @let.
  • Forgetting that a local variable can shadow a component member.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.