Rahilka Simonova is a common contributor to our blog. A few years back she wrote about React Hooks and then about Becoming a Front-End Developer in 2019. She is one of our Front-End wizards and this week she is speaking about Angular’s new control flow syntax in version 17. Rahilka is an invaluable member of our team, who has worked on numerous projects for our clients in the past 6 years.
Read what she has to say below!
(Written by Rahilka Simonova)
It’s That Time of the Year, Again!
What? Christmas? No, not yet, although in about two weeks it will begin to look a lot like Christmas.
It’s that time of the year when front-end developers from around the world get to feel the excitement of a new Angular version and everything that comes with it.
This is exactly what happened at the Special Angular Event, where the Angular team shared not only the new features but also the passion, the teamwork, and the progress that will make this version 17 a truly remarkable one.
And even if Angular is not your go-to framework, you might even have strong feelings against it, or you simply prefer using React or Vue, it’s undeniable that the Angular Momentum is real, it’s happening, and we are witnessing this Angular Renaissance through all the new features and improvements that continuously make the framework evolve.
What’s New about Angular’s Version 17 – Why All the Fuss?
Not in any particular order, but the news in Angular’s v17 include the following:
- New, built-in control flow syntax
- Deferrable views that delay loading on parts of a page
- Better SSR support
- esbuild plus Vite powered build experience
All of these topics deserve their own dedicated blog post, so for this one, I chose to dive deeper into the new control flow syntax.
How We Used to Control the Flow
Let’s take a moment here to reflect on how we controlled the flow of an Angular application so far: through structural directives. *ngIf, *ngFor, and *ngSwitch are some of the framework’s core features, that allow us to show or hide elements, iterate over arrays or objects, or display content that matches certain cases, respectively. And if you have been using Angular for a while, or at least tried it, chances are you are very familiar with these directives as well.
Throughout the years, the Angular team received a lot of community feedback about possible improvements in the control flow, so they planned to revisit it anyway at some point.
Finally, on June 14th 2023, they introduced a new RFC: Built-In Control Flow, in order to explain the whole idea behind this change, to present the new changes in detail and gather as much comments as possible on this topic. (If you haven’t seen it already, I highly recommend reading through it as it has great insights and comments too)
And here we are, a few months later, witnessing the excitement of these new features coming alive! (Technically, they’re still in developer preview, which means they might change before becoming stable, but they are ready to be tried, which is exactly what we’re going to do 😎)
The new control flow syntax is introduced with the so-called @-syntax.
So the good-old structural directives are now replaced with @if, @switch and @for.
Choosing what to show on the screen is a frequent task in our daily work, and @if condition helps us to achieve that. We also have @else if and @else blocks available.
Let’s see this in action with a very simple flow:
This looks pretty straightforward, right? It’s simple and easy to use and read. It does not require the use of the <ng-template> tag that was previously mandatory to have it in the else statement:
The same code looks very simplified with the new @if:
I like this syntax better, as it is more declarative. And I know for sure that I won’t miss those <ng-template> tags. I bet you won’t miss them too!
Up until version 16, we used *ngFor directive to repeat elements in a template.
With @for loop syntax, we have the same functionality, but with greater performance and simplified syntax.
But how much performance is a greater performance?
According to the Angular team, @for is up to 90% faster for certain list update processing, as a result of a new diffing algorithm. To establish this, an important change happened to the trackBy function: it got replaced with a track function that is mandatory and lets you specify an expression directly.
Feeling better already? I know I do, because I’m not proud of the times I have omitted using the trackBy function, which is one of the most common causes of performance issues when looping over data. So I’m more than happy to welcome this change of a mandatory track expression.
Now let’s see a comparison between *ngFor and @for when looping through an array:
Even though both code blocks have the same functionality, @for loop syntax is more compact and easier to read, as it also eliminates the need for a separate helper function.
The new syntax includes multiple implicit variables such as $index, $first, $last, $even, and $odd within iteration for each row. They can be directly used, or we can store their values in template variables if necessary.
On top of this, there is another important addition here: the @empty block. It allows us to specify what to do if the list is empty immediately:
As a reminder, with *ngFor we have to manually check this case if we want to cover this scenario. This is one way of doing it:
Looking at them side by side, I think that the @empty block is a much more convenient and intuitive way to handle empty datasets.
The updated @switch syntax replaces the *ngSwitch directive and provides a more compact and readable way of performing conditional statements based on different actions.
Let’s see @switch in action by questioning the level of excitement for the new Angular features:
This one up here seems pretty excited about it, right?
And I can see why. We’re saved from the complexity of the ngSwitch flow, and the container element that we had to include:
If you are as excited about the new Angular 17 as I am, I hope you will give it a try ASAP!
And when it comes to migration…
We might not be ready to migrate to v17 yet, and that is completely fine! In fact, the new control flow is completely optional, and the structural directives aren’t going anywhere, at least for some time. As I mentioned before, these features are in a developer preview and they might be changed until stable.
If you want to give it a try, I highly encourage you to do so. You can use the following command to make the migration automatic:
ng generate @angular-core:control-flow
And if you do so, I’m more than happy to read your thoughts on it. Happy coding! 🙋