
Angular’s template syntax supports complex JavaScript expressions but there has not been a frictionless way to store the result of an expression while still being able to reuse it across the template. Developers have had to resort to using non-ergonomic solutions to achieve this goal with directives and other solutions.
Let’s check out the new syntax:
@let name = value; // where value is a valid Angular expression
Now, within the template, a variable can be defined and used as you would expect according to Angular’s template syntax rules and conventions. For example:
@let name = 'Frodo';
<h1>Dashboard for {{name}}</h1>
Hello, {{name}}
Here’s another example of how @let can be used in a template:
<!-- Use with a template variable referencing an element --> <input #name> @let greeting = 'Hello ' + name.value; <!-- Use with an async pipe --> @let user = user$ | async;
When using the new @let declarations, keep in mind that they are scoped to the current view and its descendants, but cannot be accessed by parent or sibling views.
@let topLevel = value;
@if (condition) {
@let nested = value;
}
<div *ngIf="condition">
@let nestedNgIf = value;
</div>
<!-- Valid -->
{{topLevel}}
<!-- Error, not hoisted from @if -->
{{nested}}
<!-- Error, not hoised from *ngIf -->
{{nestedNgIf}}
@let declarations are read-only and cannot be reassigned. Their values will be recomputed on each change detection (e.g. if an async pipe changes). Attempting to write to them directly will result in a type checking error.
@let value = 10; <!-- Error: `value` is not assignable --> <button (click)="value = value + 1">Change the value</button>
Let’s explore some of the details of the syntax definition for the @let syntax. The formal definition of the new syntax is:
@let keyword.= symbol and zero or more whitespaces.; symbol.