Angular: Advantages of the revised control flow elements

What is Angular?

The web framework developed by Google Angular Angular supports developers in creating single-page web applications. Based on TypeScript, it offers a wide range of features and tools designed to optimize the development flow. Angular enables efficient two-way data binding and simplifies the synchronization of the user interface with the underlying data model.

Nglf, NgFor and NgSwitch

Anyone embarking on a journey into the world of Angular will soon encounter the control flow elements NgIf, NgFor, and NgSwitch. These directives allow you to conditionally show, hide, or repeat content. At first glance, this may seem straightforward, but a revision of the original concepts was necessary to avoid ambiguities. Since Angular 18, modified directives have been available, which primarily involve an adjustment to the syntax. In this article, I would like to introduce the revised syntax using simple examples and explain the associated advantages. Official documentation is available [here/below/etc.]. here to find. 

1. @if

The original NgIf directives are based on a simple principle: once the required condition is met, the element is displayed.

				
					@Component({ selector: 'app-root', standalone: true, template: `
   <div *ngif=condition></div>
 `, imports: [NgIf] }) export class App {}


				
			

The addition of an Else branch caused confusion: 

				
					@Component({ selector: &#039;app-root&#039;, standalone: true, template: `
   <div *ngif="condition; else falseMessage"></div>
   ...some other html content of the page...
   <ng-template #falsemessage>...</ng-template>
 `, imports: [NgIf], }) export class App {}

				
			

The syntax differed significantly from the If-Else syntax of TypeScript, which made it difficult to access and led to ambiguities. Adjusting the directive improved clarity and readability. The revised syntax is as follows: 

				
					@Component({ selector: &#039;app-root&#039;, standalone: true, template: ` @if(condition) {
     <div>Content</div>
   } @else {
     <div>False message</div>
   } `, imports: [NgIf], }) export class App {}
				
			

2. @for

Adjusting the NgFor syntax brought fewer changes. However, one important point is this: larger datasets often result in performance problems because the attribute trackBy which was easy to overlook. The original syntax:

				
					@Component({ selector: &#039;app-root&#039;, standalone: true, template: `
   <div *ngfor="let item of items">
    ...
   </div>
 `, imports: [NgFor], }) export class App { items: any[] = []; }
				
			

The Angular team opted for a simple solution: In the customized version, the attribute was track Made mandatory. Another revised point concerned the ability to check the list for emptiness without additional NgIf checks. Furthermore, several new context variables were introduced for the NgFor block, such as... $first or 1TP4 load. The complete list is here to find. The revised syntax:

				
					@Component({ selector: &#039;app-root&#039;, standalone: true, template: ` @for (item of items; track item.id) {
     <div></div>
   } @empty { List is empty } `, imports: [NgFor], }) export class App { items: any[] = []; }

				
			

3. @switch

The original concept of the three directives NgSwitch, NgSwitchCase, and NgSwitchDefault was fundamentally easy to understand and apply. The original syntax was:

				
					type State = &#039;PENDING&#039; | &#039;IN_PROGESS&#039; | &#039;DONE&#039;; @Component({ selector: &#039;app-root&#039;, standalone: true, template: `
   <div [ngswitch]="currentState">
     <ng-container *ngswitchcase="'PENDING'">Pending</ng-container>
     <ng-container *ngswitchcase="'IN_PROGRESS'">progress</ng-container>
     <ng-container *ngswitchcase="'DONE'">Done</ng-container>
     <ng-container *ngswitchdefault>No State</ng-container>
   </div>
 `, imports: [NgSwitch, NgSwitchCase, NgSwitchDefault], }) export class App { currentState!: State; }


				
			

The revised syntax, however, improved readability and more closely aligned with the familiar TypeScript syntax. The revised syntax is as follows:

				
					type State = 'PENDING' | 'IN_PROGESS' | 'DONE'; @Component({ selector: 'app-root', standalone: true, template: ` @switch (currentState) { @case ('PENDING') { Pending } @case ('IN_PROGESS') { In Progress } @case ('DONE') { Done } @default { No state } } `, imports: [NgSwitch, NgSwitchCase, NgSwitchDefault], }) export class App { currentState: State = 'PENDING'; }
				
			

Migration and backward compatibility

Angular offers the option to migrate the deprecated directive using the following command:

ng g @angular/core:control-flow

However, those who wish to continue using the familiar syntax don't have to do without it. To ensure backward compatibility, the original directives can still be used and are expected to be supported in future versions as well.

Summary

The new control flow elements in Angular improve the readability of the codebase, refine its structure, and reduce the need for unnecessary boilerplate code. They also ensure an intuitive syntax and better maintainability.

Nginx Cache for WordPress

In the world of web hosting, speed is a crucial factor for a website's success. This is where the Nginx cache comes into play, especially for WordPress websites.

Read more »

Virtual Threads in Java 21

Virtual Threads in Java: A Paradigm Shift in Concurrent Programming Introduction to Virtual Threads With the introduction of virtual threads in Java (also known as

Read more »