Exploring Angular’s New @let Syntax: Enhancing Template Variable Declarations

Netanel Basal
Netanel Basal
Published in
3 min readMay 30, 2024

Angular’s evolution continues with exciting new features, including the recently merged @let syntax, which is now avilalabe in 18.1.0-next.4. These additions offer a streamlined way for developers to declare local variables and manage control flow directly within templates. This feature aims to simplify template logic and improve readability, especially when dealing with asynchronous data and complex conditions. Let's delve into the various use cases and advantages of the new @let syntax.

Understanding the @let Syntax

The @let syntax allows developers to declare and use local variables within their Angular templates. Here's a basic example to illustrate its usage:

@let user = user$ | async;
@let greeting = user ? 'Hello, ' + user.name : 'Loading';

<h1>{{ greeting }}</h1>

In this example, user$ is an observable that emits user data. The @let syntax simplifies the process of handling asynchronous data and conditional rendering.

Use Cases for the let Syntax

Avoiding Falsy Values or Multiple Subscriptions with the Async Pipe

Managing observables and their emitted values in templates can lead to repetitive code and multiple subscriptions. Let’s look at some common issues and how @let solves them.

First, using the async pipe within an @if statement won't work correctly if the observable value is falsy (e.g., 0 or false):

@if (total$ | async as total) {
<p>{{ total }}</p>
}

Second, using the async pipe directly in multiple places can lead to multiple subscriptions, which is inefficient and can cause performance issues:

<div>{{ total$ | async }}</div>
<div>{{ total$ | async }}</div>

The solution is to use the @let syntax to declare a variable for the observable value. This approach ensures a single subscription and handles falsy values correctly.

@let total = total$ | async;

<div>{{ total }}</div>
<div>{{ total }}</div>

Signal Type Narrowing in Templates

One of the most annoying issues with signals is their lack of type narrowing ability within templates. Although Angular is working on a solution for this, we can leverage the @let feature to address this problem in the meantime:

@let txType = tx().type;

@switch(txType) {
@case('a') {}
@case('b') {}
}

@let address = person()?.address();

@if (address) {
<app-address [address]="address">
}

Inside for Loops

The @let syntax particularly useful within @for loops. Developers can create intermediate properties directly in the template, enhancing readability and reducing the need for additional component logic. For instance:

@for (user of users(); track user.id) {
@let address = user.address;

<div>
<h3>User: {{ user.name }}</h3>
<div>
<p>Street: {{ address.street }}</p>
<p>City: {{ address.city }}</p>
<p>Zipcode: {{ address.zipcode }}</p>
</div>
@for (order of user.orders) {
<div>
<h4>Order: {{ order.id }}</h4>
<p>Product: {{ order.productName }}</p>
<p>Quantity: {{ order.quantity }}</p>
</div>
}
</div>
}

Using Pipes Multiple Times

When using an expensive pipe multiple times in a template, it often necessitates creating a property in the component to store the transformed data. With the @let syntax, you can declare a transformed variable once and reuse it, reducing the computational load and keeping your template clean.

@let expensiveResult = someData | expensivePipe;

<p>{{ expensiveResult }}</p>
<p>{{ expensiveResult }}</p>

Conclusion

The @let syntax in Angular, combined with the new control flow features like @if and @for, offers a significant improvement for template variable declarations and control flow management. While some may argue for the continued use of signals for state management, the @let syntax provides an elegant solution for handling local variables within templates. By addressing common challenges such as managing falsy values, avoiding multiple subscriptions, and reducing repetitive code, this new feature is poised to enhance the development experience for Angular developers.

Follow me on Medium or Twitter to read more about Angular and JS!

--

--

Netanel Basal
Netanel Basal

Written by Netanel Basal

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.

Responses (9)