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.