Based on that documentation "
Skip to main content
v18

ctrlK
Docs
Tutorials
Playground
Reference
more_horiz
routine
Introduction
What is Angular?
Installation

Essentials
Start coding! 🚀
In-depth Guides

Components

Templates

Directives

Dependency Injection

Signals

Routing

Forms

HTTP Client

Performance

Testing

Internationalization

Animations

Experimental features
Developer Tools

Angular CLI

Libraries
DevTools
Language Service
Best Practices
Style Guide
Security
Accessibility

Performance
Keeping up-to-date
Extended Ecosystem

Service Workers & PWAs
Web workers
Angular Fire
Google Maps
Google Pay
YouTube player
Angular CDK
Angular Material

arrow_back
Templates
Overview
Binding dynamic text, properties and attributes
Adding event listeners
Two-way binding
Control flow
Pipes
Slotting child content with ng-content
Create template fragments with ng-template
Grouping elements with ng-container
Variables in templates
Deferred loading with @defer
Expression syntax
Whitespace in templates
In-depth Guides
Templates
Variables in templates
edit
Angular has two types of variable declarations in templates: local template variables and template reference variables.

On this page
Local template variables with @let
Using @let
Referencing the value of @let
Assignability
Variable scope
Full syntax
Template reference variables
Declaring a template reference variable
Assigning values to template reference variables
Using template reference variables with queries

arrow_upward_alt
Back to the top
Local template variables with @let
Angular's @let syntax allows you to define a local variable and re-use it across a template, similar to the JavaScript let syntax.

IMPORTANT: the @let syntax is currently in Developer Preview.

Using @let
Use @let to declare a variable whose value is based on the result of a template expression. Angular automatically keeps the variable's value up-to-date with the given expression, similar to bindings.

@let name = user.name;
@let greeting = 'Hello, ' + name;
@let data = data$ | async;
@let pi = 3.1459;
@let coordinates = {x: 50, y: 100};
@let longExpression = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit ' +
                      'sed do eiusmod tempor incididunt ut labore et dolore magna ' +
                      'Ut enim ad minim veniam...';
check
Each @let block can declare exactly one variable. You cannot declare multiple variables in the same block with a comma.

Referencing the value of @let
Once you've declared a variable with @let, you can reuse it in the same template:

@let user = user$ | async;
@if (user) {
  <h1>Hello, {{user.name}}</h1>
  <user-avatar [photo]="user.photo"/>
  <ul>
    @for (snack of user.favoriteSnacks; track snack.id) {
      <li>{{snack.name}}</li>
    }
  </ul>
  <button (click)="update(user)">Update profile</button>
}
check
Assignability
A key difference between @let and JavaScript's let is that @let cannot be reassigned after declaration. However, Angular automatically keeps the variable's value up-to-date with the given expression.

@let value = 1;
<!-- Invalid - This does not work! -->
<button (click)="value = value + 1">Increment the value</button>
check
Variable scope
@let declarations are scoped to the current view and its descendants. Angular creates a new view at component boundaries and wherever a template might contain dynamic content, such as control flow blocks, @defer blocks, or structural directives.

Since @let declarations are not hoisted, they cannot be accessed by parent views or siblings:

@let topLevel = value;
<div>
  @let insideDiv = value;
</div>
{{topLevel}} <!-- Valid -->
{{insideDiv}} <!-- Valid -->
@if (condition) {
  {{topLevel + insideDiv}} <!-- Valid -->
  @let nested = value;
  @if (condition) {
    {{topLevel + insideDiv + nested}} <!-- Valid -->
  }
}
<div *ngIf="condition">
  {{topLevel + insideDiv}} <!-- Valid -->
  @let nestedNgIf = value;
  <div *ngIf="condition">
     {{topLevel + insideDiv + nestedNgIf}} <!-- Valid -->
  </div>
</div>
{{nested}} <!-- Error, not hoisted from @if -->
{{nestedNgIf}} <!-- Error, not hoisted from *ngIf -->
check
Full syntax
The @let syntax is formally defined as:

The @let keyword.
Followed by one or more whitespaces, not including new lines.
Followed by a valid JavaScript name and zero or more whitespaces.
Followed by the = symbol and zero or more whitespaces.
Followed by an Angular expression which can be multi-line.
Terminated by the ; symbol.
Template reference variables
Template reference variables give you a way to declare a variable that references a value from an element in your template.

A template reference variable can refer to the following:

a DOM element within a template (including custom elements)
an Angular component or directive
a TemplateRef from an ng-template
You can use template reference variables to read information from one part of the template in another part of the same template.

Declaring a template reference variable
You can declare a variable on an element in a template by adding an attribute that starts with the hash character (#) followed by the variable name.

<!-- Create a template reference variable named "taskInput", referring to the HTMLInputElement. -->
<input #taskInput placeholder="Enter task name">
check
Assigning values to template reference variables
Angular assigns a value to template variables based on the element on which the variable is declared.

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

<!-- The `startDate` variable is assigned the instance of `MyDatepicker`. -->
<my-datepicker #startDate />
check
If you declare the variable on an <ng-template> element, the variable refers to a TemplateRef instance which represents the template. For more information, see How Angular uses the asterisk, *, syntax in Structural directives.

<!-- The `myFragment` variable is assigned the `TemplateRef` instance corresponding to this template fragment. -->
<ng-template #myFragment>
  <p>This is a template fragment</p>
</ng-template>
check
If you declare the variable on any other displayed element, the variable refers to the HTMLElement instance.

<!-- The "taskInput" variable refers to the HTMLInputElement instance. -->
<input #taskInput placeholder="Enter task name">
check
Assigning a reference to an Angular directive
Angular directives may have an exportAs property that defines a name by which the directive can be referenced in a template:

@Directive({
  selector: '[dropZone]',
  exportAs: 'dropZone',
})
export class DropZone { /* ... */ }
check
When you declare a template variable on an element, you can assign that variable a directive instance by specifying this exportAs name:

<!-- The `firstZone` variable refers to the `DropZone` directive instance. -->
<section dropZone #firstZone="dropZone"> ... </section>
check
You cannot refer to a directive that does not specify an exportAs name.

Using template reference variables with queries
In addition to using template variables to read values from another part of the same template, you can also use this style of variable declaration to "mark" an element for component and directive queries.

When you want to query for a specific element in a template, you can declare a template variable on that element and then query for the element based on the variable name.

 <input #description value="Original description">
check
@Component({
  /* ... */,
  template: `<input #description value="Original description">`,
})
export class AppComponent {
  // Query for the input element based on the template variable name.
  @ViewChild('description') input: ElementRef | undefined;
}
check
See Referencing children with queries for more information on queries.

Social Media
Blog
X (formerly Twitter)
YouTube
Discord
GitHub
Stack Overflow
Community
Contribute
Code of Conduct
Report Issues
Google's DevLibrary
Angular Google Developer Experts
Resources
Press Kit
Roadmap
Languages
简体中文版
正體中文版
日本語版
한국어
Ελληνικά
Super-powered by Google ©2010-2024. Code licensed under an MIT-style License . Documentation licensed under CC BY 4.0 .

" and this component "output-console.component.html (1-28)


@if (this.consoleData() && this.consoleData().length > 0) {
  <div class="border bg-body-secondary console">
    <samp>
      @let detectedLanguage = detectLanguage(this.consoleData()[0]);

      @for (data of this.consoleData(); track data) {
        @switch (detectedLanguage) {
          @case ("json") {
            <pre><code [highlight]="data | prettyJson" language="json"></code></pre>
          }
          @case ("xml") {
            <pre><code [highlight]="data | prettyXml"  language="xml"></code></pre>
          }
          @case ("csv") {
            <div>
              <!-- CSV Table Rendering -->
            </div>
          }
          @default {
            <pre><code>{{ data }}</code></pre>
          }
        }
      }
    </samp>
  </div>
}


output-console.component.ts (1-38)


import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { Highlight } from 'ngx-highlightjs';
import { PrettyJsonPipe } from '../shared/pipes/pretty-json.pipe';
import { PrettyXmlPipe } from '../shared/pipes/pretty-xml.pipe';

@Component({
  selector: 'app-output-console',
  standalone: true,
  imports: [CommonModule, Highlight, PrettyJsonPipe, PrettyXmlPipe],
  templateUrl: './output-console.component.html',
  styleUrl: './output-console.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class OutputConsoleComponent {
  public consoleData = input.required<string[]>();

  public detectLanguage(data: string): string {
    data = data.trim();
    try {
      JSON.parse(data);
      return 'json';
    } catch {
      // Not JSON
    }

    if (data.startsWith('<')) {
      return 'xml';
    }

    if (data.includes(',') || data.includes('\n')) {
      return 'csv';
    }

    return 'plaintext';
  }
}


" and this error " [ERROR] NG5002: Incomplete block "let detectedLanguage". If you meant to write the @ character, you should use the "&#64;" HTML entity instead. [plugin angular-compiler]

    src/app/output-console/output-console.component.html:4:6:
      4 │       @let detectedLanguage = detectLanguage(this.consoleData()[0]);
        ╵       ~~~~~~~~~~~~~~~~~~~~~~

  Error occurs in the template of component OutputConsoleComponent.

    src/app/output-console/output-console.component.ts:11:15:
      11 │   templateUrl: './output-console.component.html',
         ╵                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Application bundle generation failed. [0.593 seconds]

X [ERROR] NG5002: Incomplete block "let detectedLanguage". If you meant to write the @ character, you should use the "&#64;" HTML entity instead. [plugin angular-compiler]

    src/app/output-console/output-console.component.html:4:6:
      4 │       @let detectedLanguage = detectLanguage(this.consoleData()[0]);
        ╵       ~~~~~~~~~~~~~~~~~~~~~~

  Error occurs in the template of component OutputConsoleComponent.

    src/app/output-console/output-console.component.ts:11:15:
      11 │   templateUrl: './output-console.component.html',
         ╵                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

" can you help me fix that?