Angular is getting New Template Syntax
Daniel Glejzner
Posted on July 1, 2023
Update 2023–10–07: I have updated this to the final syntax form with @
New Template Syntax, Built-In Control Flow, a farewell to structural directives? Not a lot has been changing in recent years. Angular has been stable for some devs and stagnant for others. Now it’s moving forward at light speed. But where exactly is it headed?
Angular proposes a transition from the current structural directives (NgIf, NgForOf, NgSwitch) to a new built-in syntax. If you’re not already following the RFCs (Request for Comments), please do. In meantime I am going to help you understand what’s coming.
Revamping Control Flow
Angular team aims to replace the existing structural directives (NgIf, NgForOf, and NgSwitch) with a more modern, macro-like syntax. While the structural directives are not going away completely, because the concept is going to stay — this new way of writing your template is going to be the preferred one. It’s backwards compatible and for some time you are going to be able to use both old template style and new one in different files.
Change aims to cover better readability and provide smother way to adapt for wider audience in Frontend world.
Before
The trackByFunction in Angular is a custom function used for optimizing performance when iterating over large collections using *ngFor
. In current syntax it takes only a function, in new way it’s going to work just with properties.
Angular will track changes in the collection based on each item’s id, instead of its identity. This is useful when items in the collection have unique ids, improving efficiency when the collection is updated.
trackByFunction(index, item) {
return item.id;
}
<div *ngFor="let item of items; index as idx; trackBy: trackByFunction">
Item #{{ idx }}: {{ item.name }}
</div>
After
@for (item of items; track item.id; let idx = $index, let e = $even)
{
Item #{{ idx }}: {{ item.name }}
}
This new syntax is keeping several implicit variables like $index, $first, $last, $even, and $odd within for row views. These are available for use directly, but can also be aliased using the ‘let’ segment. The new syntax also emphasizes using ‘track’ for loops to improve performance and optimizes list diffing by enforcing tracking.
@for (item of items; track item.id)
{
{{ item }}
}
@empty
{
There were no items in the list.
}
One crucial feature introduced is the ‘empty’ block which allows developers to display a template when there are no items in the list. Also, Angular is changing how it handles list diffing. Rather than using the customizable IterableDiffers, Angular will provide a new optimized algorithm for better performance.
If-Else Blocks
If you found the original way of working with ng-container & ng-template alongside *ngIf
structural directive not intuitive enough — New Control Flow might have an answer for your troubles.
Before (in theory)
<ng-container *ngIf="cond.expr; else elseBlock">
Main case was true!
</ng-container>
<ng-template #elseBlock>
<ng-container *ngIf="other.expr; else finalElseBlock">
Extra case was true!
</ng-container>
</ng-template>
<ng-template #finalElseBlock>
False case!
</ng-template>
After
@if (cond.expr)
{
Main case was true!
}
@else if (other.expr)
{
Extra case was true!
}
@else
{
False case!
}
Switch Block
The ‘switch’ block takes place of *ngSwitch
which. New way of writing is said to bring in substantial benefits like enhanced template type-checking and no need for container elements to hold condition expressions. Here’s a quick peek at how it would look:
@switch (condition)
{
@case (caseA)
{
Case A.
}
@case (caseB)
{
Case B.
}
@default
{
Default case.
}
}
What About Migration?
Migration to the new syntax is promised be relatively smooth. Angular team is working on an automated migration schematic to convert from the old to the new syntax. However, developers might need to be cautious about any custom diffing algorithm used in their applications as it could affect the new ‘for’ directive’s behavior.
Future Opportunities
The Angular team envisions extending this new syntax to accommodate more JS loop flavors, including async iteration, and for-in loops. Potential future improvements also include virtual scrolling and destructuring support.
There is also another RFC showing new feature in action — this feature is based new Built-In Control Flow. Checkout RFC for Deferred Loading
FAQ Recap
Let’s quickly address some common concerns developers might have about this new control flow syntax:
Existing structural directives: The current structural directives (NgIf, etc) will continue to work. However, Angular will strongly encourage developers to switch to the new syntax.
Structural directive concept: It will not be removed and remains an essential feature in Angular.
Syntax highlighting: Yes, the Angular Language Service will highlight keywords and expressions within the new control flow blocks.
Effect on query results: The new control flow will not affect query results.
Need to import new control flow: No, it will be built into the template language and automatically available to all components.
Performance: The new control flow might offer marginal improvements, particularly for ‘for’ and diffing.
Custom block groups and directives: At present, the new syntax doesn’t support libraries to define custom block groups, and you can’t add directives to the new control flow blocks.
What do you think?
This proposed syntax change is going to affect the way you write your templates. Do you think it’s needed? Is this change going to improve your DX and bring new devs aboard that prevously preferred to use different frameworks?
My main concerns lie within the transition period. We have a significant change in reactive primitive with Signals and now new Template Syntax is being introduced. It’s definitely coming together to paint a bigger picture that hasn’t been unveiled to us yet. For some time Angular devs are going to get many options to handle reactivity: RxJS, Signals, Promises, Change Detection (zone.js) + 2 ways of writing templates.
It will definitely take a long time to fully transition to the new vision and it’s not like you can speed this process up. Now the question would be, is the cost of these advancements worth what we are getting in the end?
Make sure to let me know and have a discussion!
I hope you liked my article!
If you did you might also like what I am doing on Twitter. I am hosting live Twitter Spaces about Angular with GDEs & industry experts! You can participate live, ask your questions or watch replays in a form of short clips :)
If you are interested drop me a follow on Twitter @DanielGlejzner — would mean a lot :). Thank You!
Oh no! My Coffee cup is empty :( …
… if you want to refill go ahead :) https://ko-fi.com/danielglejzner
Posted on July 1, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 11, 2024
November 22, 2024