DEV Community

Cover image for Transitioning to Angular 17's New Control Flow Syntax
Dimitris Kiriakakis
Dimitris Kiriakakis

Posted on • Updated on

Transitioning to Angular 17's New Control Flow Syntax

Hello, Angular developers! After recently migrating some templates of our current project to Angular 17's new control flow syntax, I thought that sharing some of my insights would help some of you smoothly transition to this new syntax, providing clear and distinct examples for each control flow construct. So here we go..

Traditional Directives vs. Angular 17's Control Flow Syntax

Let's compare traditional directives with Angular 17's control flow using some examples:

1. *ngIf Directive vs @if Control Block

Before (Traditional *ngIf):

<div *ngIf="isLoggedIn">
  Welcome back, user!
</div>
Enter fullscreen mode Exit fullscreen mode

After (Angular 17's @if):

<div> @if (isLoggedIn) { Welcome back, user! } </div>
Enter fullscreen mode Exit fullscreen mode

2. *ngIf Directive and async Pipe vs @if and async

Before (async Pipe with *ngIf):

<div *ngIf="user$ | async as user">
  Hello, {{ user.name }}!
</div>
Enter fullscreen mode Exit fullscreen mode

After (async with Angular 17's @if):

<div> @if (user$ | async as user) { Hello, { {user.name} }! } </div>
Enter fullscreen mode Exit fullscreen mode

3. *ngFor Directive vs @for Control Block

Before (Traditional *ngFor):

<ul>
  <li *ngFor="let item of items">{{ item }}</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

After (Angular 17's @for):

<ul>
  @for (item of items; track item) {
    <li> { {item} } </li>
  }
</ul>
Enter fullscreen mode Exit fullscreen mode

4. ngSwitch Directive vs @switch Control Block

Before (Traditional [ngSwitch]):

<div [ngSwitch]="userRole">
  <span *ngSwitchCase="'admin'">Admin Access</span>
  <span *ngSwitchCase="'user'">User Access</span>
  <span *ngSwitchDefault>Guest Access</span>
</div>
Enter fullscreen mode Exit fullscreen mode

After (Angular 17's @switch):

<div>
  @switch (userRole) {
    @case 'admin': { <span>Admin Access</span> } 
    @case 'user': { <span>User Access</span> } 
    @default: { <span>Guest Access</span> }
  }
</div>
Enter fullscreen mode Exit fullscreen mode

New template control block introduced in Angular 17

Lazy-Loading template parts with @defer

<div>
  @defer (loadExpensiveComponent) {
    <app-expensive-component></app-expensive-component>
  }
</div>
Enter fullscreen mode Exit fullscreen mode

Make sure that you check out the Deferrable Views documentation for more information about the @defer block and how you can utilise the trigger conditions it offers.

Some Migration Tips

  • Start with simple components: Gradually move to more complex ones.
  • Utilise automated Migration: Use the Angular v17 CLI's migration command.
ng g @angular/core:control-flow
Enter fullscreen mode Exit fullscreen mode

Or better do it in smaller steps.

ng g @angular/core:control-flow --path=./src/component-to-be-migrated
Enter fullscreen mode Exit fullscreen mode
  • Escape {, } and @ characters: Existing usages of {, } and @ as literal characters in templates will have to be escaped.
  • Manual Refinement: Fine-tune complex templates manually for optimal use of the new syntax. For instance, in some cases you could use @defer blocks to load content lazily.

Backward Compatibility and Performance

Angular 17 allows you to use both the new and the traditional syntaxes in your applications. And in terms of performance it's worth mentioning that the Angular team has observed up to 90% speed performance improvements when using the new syntax.

Conclusion

The introduction of Angular 17's new control flow syntax marks a significant improvement in how we handle template and rendering logic in our Angular applications. The transition to this new syntax, promises to make our code more readable, maintainable, and performant.

As we have experienced in our own project, these changes are not just cosmetic but functional, levelling up the way we work with Angular.

Top comments (2)

Collapse
 
yording profile image
Yording

The @for requires the use of track, otherwise it throws an error

Collapse
 
dimeloper profile image
Dimitris Kiriakakis

Correct @yording , thank you.