Angular is getting New Template Syntax

danielglejzner

Daniel Glejzner

Posted on July 1, 2023

Angular is getting New Template Syntax

Generated by MidJourney AI

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.

Generated by MidJourney AI

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>


Enter fullscreen mode Exit fullscreen mode

After



@for (item of items; track item.id; let idx = $index, let e = $even) 
{
  Item #{{ idx }}: {{ item.name }}
}


Enter fullscreen mode Exit fullscreen mode

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.
}


Enter fullscreen mode Exit fullscreen mode

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.

Generated by MidJourney AI

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>


Enter fullscreen mode Exit fullscreen mode

After



@if (cond.expr) 
{
  Main case was true!
} 
@else if (other.expr) 
{
  Extra case was true!
} 
@else 
{
  False case!
}


Enter fullscreen mode Exit fullscreen mode

Generated by MidJourney AI

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.
  }
}


Enter fullscreen mode Exit fullscreen mode

Generated by MidJourney AI

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.

Generated by MidJourney AI

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

Generated by MidJourney AI

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.

Generated by MidJourney AI

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

💖 💪 🙅 🚩
danielglejzner
Daniel Glejzner

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