Angular Control Flow
A new modern way of writing ifs, if-else, switch-cases, and even loops in Angular templates!
Kevin Kreuzer
@kreuzercode
Oct 24, 2023
5 min read
(đ¸ by Javier MartĂnez)
Angular 17 is around the corner with a brand new template feature named control flow. The control flow is a new way of writing if
statements, if-else
statements, switch-case
statements and for
loops.
Additionally, Angular 17 will introduce âDeferable Views,â an exciting feature which we will cover in another blog post. Subscribe to our newsletter to not miss it!{:target="_blank"}
Letâs dive into the future of Angular and explore how weâll be crafting our if-else
, switch-case
, and for
loops. Weâll begin with the straightforward yet fundamental example: the humble if
condition.
The @if conditions
Up until now, Angular has allowed us to create simple if statements with the usage of the NgIf
directive.
<div *ngIf="condition">Content</div>
To compile this code, we had to add the NgIf
directive to our components imports array. The complete component code would look like this.
@Component({
standalone: true,
template: `<div *ngIf="condition">Content</div>`,
imports: [NgIf],
})
export class MyComponent {}
Great, now letâs explore how we can shake things up in Angular 17 by using the fresh and exciting control flow syntax to rewrite this code.
@if (condition) {
<div>Content</div>
}
Indeed, the syntax is strikingly similar to a regular JavaScript function. The only noticeable difference is that little @
symbol at the start of our if
statement.
Okay, pretty easy. What about an if-else
?
If you are not familiar with the syntax yet, just ask yourself, how would I write an
if/else
in JavaScript and then add prefix the keywords with an@
symbol.
@if (streamingService === 'Netflix'){
<div>Peaky Blinders</div>
} @else {
<div>Ted Lasso</div>
}
𤊠Straight forward. Just prefix the if
and else
keywords with an @
and return templates in the function bodies instead of log statements.
Okay, wow, an if-else
statement. Why are you so excited? Well, currently we would have to write the following to achieve the same.
<div *ngIf="streamingService === 'Netflix'; else appleTVShow">
Peaky Blinders
</div>
<ng-template #appleTVShow>
<div>Ted Lasso</div>
</ng-template>
To me, the new approach dramatically improves readability. Also, it is way easier to teach since it is very close to the JavaScript syntax.
Which one do you prefer? Which one do you find more readable? Let us know in the comments.
Thatâs all we need to know regarding control flow and if-else
, on to switch-case
statements.
The @switch case
The Switch-Case statement allows you to evaluate an expression and execute different blocks of code based on the matched case, making it a useful tool for handling multiple branching conditions.
In the current Angular version, we were able to write a switch-case
statement by adding the following directives to our components or modules imports array: NgSwitch
, NgSwitchCase
and NgSwitchDefault
. The HTML code then looks like this:
<div [ngSwitch]="streamingService">
<div *ngSwitchCase="'AppleTV'">Ted Lasso</div>
<div *ngSwitchCase="'Disney+'">Mandalorian</div>
<div *ngSwitchDefault>Peaky Blinders</div>
</div>
Letâs rewrite this to the new control flow syntax.
@switch(streamingService) {
@case ('Disney+') {
<div>'Mandalorian'</div>
} @case ('AppleTV') {
<div>'Ted Lasso'</div>
} @default {
<div>'Peaky Blinders'</div>
}
}
Again, this code is close to the JavaScript version but instead of using
:
we use curly brackets for our case statements.
Great, whoâs ready to dive into loops?
The @for loops
Loops play a crucial role in virtually every application because they serve as fundamental building blocks for working with lists and data. Today Angular provides us the ngFor
directive.
<ul>
<li *ngFor="let streamingService of streamingServices">
{{streamingService}}
</li>
</ul>
Letâs take a look at how we write such a loop inside an Angular template using the new control flow syntax.
<ul>
@for (streamingService of streamingServices; track streamingService) {
<li>{{streamingService}}</li>
}
</ul>
We can see some differences here. Firstly, weâre missing the let
keyword in front of the variable definition, and secondly, weâre introducing the track
function.
New better "track"
Does track
ring a bell? It might remind you of the optional trackBy
function weâve been using with ngFor
so far.
In Angular, the
trackBy
function is used with thengFor
directive to optimize rendering of lists. It assigns a unique identifier to each item in the list, allowing Angular to efficiently update and modify individual items without re-rendering the entire list. This improves performance, especially with large lists.
âď¸ Did you ever experience performance issues with bigger lists? Well, maybe it has to do with not using the
trackBy
function. In a performance research, the Angular team found out thatNgFor
loops over immutable data withouttrackBy
is one of the most common causes of performance issues across Angular applications.
Due to the risk of performance issues, the track function is now required for for
loops.
The nice thing about track
is that we can now write our whole expression inline and there's no need for a dedicated function in our template.
@for (product of products; track product.id) {
{{ product.title }}
}
Itâs still possible to invoke
trackBy
function via track. This will mainly be used for migration purposes.
@for (product of products; track productId($index, product)) {
{{ product.title}}
}
Implicit variables
In the new control flow syntax the following variables will be available within a for row view.
To access those variables we have to use the let keyword to assign them to a variable of our choice.
<ul>
@for (service of streamingServices; track service; let i =
$index; let first = $first; let last = $last; let even = $even; let odd = $odd
) {
<li>{{i}} {{first}} {{last}} {{even}} {{odd}}</li>
}
</ul>
Exciting, isnât it? But thatâs not all, there's a brand new feature, an @empty
block.
Empty block
The use of an @empty
block provides us with the ability to render an element even when the list is empty.
Letâs say we have a list where we display all the streaming services a user is currently subscribed to. If the user doesnât have any streaming service subscriptions we display a div with a message. This is a perfect use case for the @empty
block.
@for (streamingService of streamingServices; track stramingService) {
<div>{{ streamingService }}</div>
} @placeholder {
<div>No streaming services available</div>
}
Automatic migration
If you, like me, are a fan of the new, more readable syntax, you might just feel like giving your codebase a nice makeover to adopt this fresh approach to control flow. But that could result in a lot of work, since ngIf
and ngFor
statements are used all over your application.
But donât worry Angular provides an epic migration command that will migrate our application to the new control flow syntax.
ng g @angular/core:control-flow
In conclusion, the new control flow syntax is a change that not only improves the readability of our code but also makes it more intuitive and elegant. As a fan of these enhancements, I truly believe that they are a step in the right direction, making our codebases cleaner and more efficient.
So, donât forget to let us know your thoughts in the comments, as weâre eager to hear your perspective on this exciting development. Happy coding!
Further resources
If youâre curious to learn more about the awesome new control flow, feel free to check out my Stream VOD and take a peek at the introduction video showcasing this nifty feature. Itâs a fun way to get the lowdown on what the control flow is all about!
Do you enjoy the theme of the code preview? Explore our brand new theme plugin
Skol - the ultimate IDE theme
Northern lights feeling straight to your IDE. A simple but powerful dark theme that looks great and relaxes your eyes.
Do you enjoy the content and would like to learn more about how to ensure long term maintainability of your Angular application?
Angular Enterprise Architecture eBook
Learn how to architect a new or existing enterprise grade Angular application with a bulletproof tooling based automated architecture validation.
This will ensure that Your project stays maintainable, extendable and therefore with high delivery velocity over the whole project lifetime!
Get notified
about new blog posts
Sign up for Angular Experts Content Updates & News and you'll get notified whenever we release a new blog posts about Angular, Ngrx, RxJs or other interesting Frontend topics!
We will never share your email with anyone else and you can unsubscribe at any time!
Responses & comments
Do not hesitate to ask questions and share your own experience and perspective with the topic
Nivek
Google Developer Expert (GDE)
for Angular & Web Technologies
A trainer, consultant, and senior front-end engineer with a focus on the modern web, as well as a Google Developer Expert for Angular & Web technologies. He is deeply experienced in implementing, maintaining and improving applications and core libraries on behalf of big enterprises worldwide.
Kevin is forever expanding and sharing his knowledge. He maintains and contributes to multiple open-source projects and teaches modern web technologies on stage, in workshops, podcasts, videos and articles. He is a writer for various tech publications and was 2019âs most active Angular In-Depth publication writer.
58
Blog posts
2M+
Blog views
39
NPM packages
4M+
Downloaded packages
100+
Videos
15
Celebrated Champions League titles
You might also like
Check out following blog posts from Angular Experts to learn even more about related topics like Modern Angular !
Top 10 Angular Architecture Mistakes You Really Want To Avoid
In 2024, Angular keeps changing for better with ever increasing pace, but the big picture remains the same which makes architecture know-how timeless and well worth your time!
Tomas Trajan
@tomastrajan
Sep 10, 2024
15 min read
Total guide to lazy loading with Angular @defer
Learn everything about the lazy loading of standalone components with Angular @defer block including best practices, deep dive on all interactions and gotchas including a live demo!
Tomas Trajan
@tomastrajan
Nov 14, 2023
13 min read
How to migrate Angular CoreModule to standalone APIs
Let's learn how to migrate commonly used Angular CoreModule (or any other Angular module) to standalone APIs to fully embrace standalone project setup!
Tomas Trajan
@tomastrajan
Sep 5, 2023
9 min read
Empower your team with our extensive experience
Angular Experts have spent many years consulting with enterprises and startups alike, leading workshops and tutorials, and maintaining rich open source resources. We take great pride in our experience in modern front-end and would be thrilled to help your business boom