Angular 17: New control flow syntax

Alain Chautard
Angular Training
Published in
4 min readNov 7, 2023

--

Angular 17 has an updated logo and brand identity, a new website (angular.dev), and many more features that will be covered in my Daily Angular Newsletter over the next few days.

In this article, let’s cover the new control flows available in our Angular HTML templates.

New “If — then — else” syntax

We’re used to the ngIf directive and its cumbersome “else” syntax as follows:

<div *ngIf="condition; else elseBlock">
Content to render when the condition is true.
</div>
<ng-template #elseBlock>
Content to render when the condition is false.
</ng-template>

Here’s the new syntax introduced in Angular 17:

<div>
@if (condition) {
Content to render when the condition is true.
} @else {
Content to render when the condition is false.
}
</div>

It’s much more concise and readable. It also comes with an else if option:

@if (a > b) {
{{a}} is greater than {{b}}
} @else if (b > a) {
{{a}} is less than {{b}}
} @else {
{{a}} is equal to {{b}}
}
Subscribe to the Daily Angular Newsletter!

New “for” loop syntax

The ngFor directive can also be replaced with a similar syntax:

@for (item of items; track item.id) {
{{ item.name }}
}

Note that the track parameter is required, but unlike ngFor’s trackBy, it doesn’t require a function and can use an object’s property instead.

Of course, the contextual variables we had with ngFor are still available to get the index of an element or more row information:

@for (item of items; track item.id; let idx = $index, e = $even) {
Item #{{ idx }}: {{ item.name }}
}
Different local variables available in the context of a “for” loop

A new feature is that we can define an alternate template to display if the array is empty with the @empty block:

@for (item of items; track item.name) {
<li> {{ item.name }} </li>
} @empty {
<li> There are no items. </li>
}
Angular Certification Exam

New “switch — case” syntax

Another directive that gets a better syntax alternative is ngSwitch and its not-so-obvious syntax:

<div [ngSwitch]="page">
<p *ngSwitchCase="1">Viewing content of first page</p>
<p *ngSwitchCase="2">Viewing content of second page</p>
<p *ngSwitchCase="3">Viewing content of third page</p>
<p *ngSwitchDefault>No page selected</p>
</div>

With Angular 17, there’s a lot less confusion syntax-wise:

@switch (page) {
@case (1) {
<p>Viewing content of first page</p>
}
@case (2) {
<p>Viewing content of second page</p>
}
@default {
<p>No page selected</p>
}
}

Important notes

While those new syntaxes are available with Angular 17, it is essential to mention that:

  • Legacy Angular directives such as ngIf, ngFor, and ngSwitch are not deprecated and are not going away any time soon.
  • You can use both syntaxes in your Angular 17+ app if you want
  • There is an automated Angular CLI migration command available if you want to replace the legacy syntax automatically: ng g @angular/core:control-flow
  • It’s not just about syntax: The Angular team measured up to 90% speed performance improvements when using the new syntax and an average of 30% speed improvement on the Angular Material repo.

That’s a lot of news, and we’re just scratching the surface of what Angular 17 offers. Tomorrow, I’ll cover deferred views in the Daily Angular Newsletter blog.

My name is Alain Chautard. I am a Google Developer Expert in Angular and a consultant and trainer at Angular Training, where I help web development teams learn and become comfortable with Angular.

If you need any help with web development, feel free to get in touch!

If you enjoyed this article, please clap for it or share it. Your help is always appreciated. You can also subscribe to my articles and to the Daily Angular Newsletter to receive helpful daily tips.

--

--