Transitioning to Angular's New Control Flow Syntax
Tags: angular, frontend, typescript, tutorial
Published: 2023-11-28 20:11:28

Hello, Angular developers! After recently migrating some templates of our current project to Angular'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's Control Flow Syntax

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

**1. `*ngIf` Directive vs `@if` Control Block**

Before (Traditional `*ngIf`):

```html
<div *ngIf="isLoggedIn">
  Welcome back, user!
</div>
```

After (Angular's control flow `@if`):

```html
<div> @if (isLoggedIn) { Welcome back, user! } </div>
```

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

Before (`async` Pipe with `*ngIf`):

```html
<div *ngIf="user$ | async as user">
  Hello, {{ user.name }}!
</div>
```

After (`async` with Angular's control flow `@if`):

```html
<div> @if (user$ | async as user) { Hello, { {user.name} }! } </div>
```

**3. `*ngFor` Directive vs `@for` Control Block**

Before (Traditional `*ngFor`):

```html
<ul>
  <li *ngFor="let item of items">{{ item }}</li>
</ul>
```

After (Angular's control flow `@for`):

```html
<ul>
  @for (item of items; track item) {
    <li> { {item} } </li>
  }
</ul>
```

**4. `ngSwitch` Directive vs `@switch` Control Block**

Before (Traditional `[ngSwitch]`):

```html
<div [ngSwitch]="userRole">
  <span *ngSwitchCase="'admin'">Admin Access</span>
  <span *ngSwitchCase="'user'">User Access</span>
  <span *ngSwitchDefault>Guest Access</span>
</div>
```

After (Angular's control flow `@switch`):

```html
<div>
  @switch (userRole) {
    @case ('admin') { <span>Admin Access</span> } 
    @case ('user') { <span>User Access</span> } 
    @default { <span>Guest Access</span> }
  }
</div>
```

## New template control block introduced in Angular control flow syntax

Lazy-Loading template parts with `@defer`

```html
<div>
  @defer (loadExpensiveComponent) {
    <app-expensive-component></app-expensive-component>
  }
</div>
```

Make sure that you check out the [Deferrable Views](https://angular.io/guide/defer) 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 CLI's migration command.

```bash
ng g @angular/core:control-flow
```

  Or better do it in smaller steps.

```bash
ng g @angular/core:control-flow --path=./src/component-to-be-migrated
```
- 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

Latest versions of Angular allow 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'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.