Performance and template syntax

Today, I’d like to challenge you with a small exercise. Take a minute to examine the three following code examples and decide which option performs best. Note how similar those three options are from a syntax standpoint, yet they yield very different results performance-wise:

Example #1 – Array of data

<div *ngFor="let data of getData()">{{data.name}}</div>

Example #2 – Observable

<div *ngFor="let data of getData() | async">{{data.name}}</div>

Example #3 – Signal

<div *ngFor="let data of dataSignal()">{{data.name}}</div>

Feel free to list the pros and cons of each approach. You can even respond to that email with your answers if you want. Tomorrow, I’ll give you my insights.

Increasing binding specificity

Let’s say we want to trigger an action when the user hits enter on their keyboard. We could do something like this, capturing the keydown event and then decide what to do based on the entered key:

While the above works, it’s pretty verbose. Instead, we can make our binding more specific by doing the following:

Now, that’s a lot more specific and less verbose. The same goes for class bindings. Here’s a lengthy example:

Since all we want to do is toggle the green class on or off based on a boolean expression, the following syntax is shorter and better:

You can see these examples in action on Stackblitz.

Combining multiple Observables with ngrxLet

Last month, I explained how to use ngrxLet to render a loading template. Earlier this year, I also covered how ngrxLet can be a great alternative to the async pipe. All in all, ngrxLet is a fantastic directive that keeps improving.

For instance, we can also use it to combine multiple different Observables into one local variable as follows:

Without ngrxLet, the equivalent code would have to use the async pipe syntax trick covered last week:

This also works, but it’s more verbose and has the downside of using ngIf, which is present only because we need a structural directive to enable the local variable assignment micro-syntax.

ng-class for dynamic styling

This is a guest post by Tomas Kotlar. Thanks for your contribution, Tomas! Remember than anyone can reach out to me to contribute or suggest post ideas.

ngClass, as defined by the Angular documentation, is a built-in attribute directive that dynamically modifies the behavior of other HTML elements.

Common use cases

Conditional Styling

Let’s consider a button element that changes color based on whether it’s disabled or active. We can use ngClass to toggle between the ‘active-btn’ and ‘disabled-btn’ classes, giving the button a responsive touch:

Whenever the button is clicked, the toggleDisabled() function will be executed, toggling the value of isDisabled.

As a result, the button will become enabled or disabled based on the updated value of isDisabled, and the corresponding style (active or disabled) will be applied.

Using an Object

ngClass goes beyond just toggling classes. It also lets you iterate over object properties to apply your styles conditionally. This can be handy when working with data-driven apps or displaying dynamic content.

For example, using the following data:

In our HTML, we can apply dynamic styles using an array:

Based on the type (‘hero’ or ‘villain’), the directive applies the appropriate highlight class to the hero card.

Combining classes using conditions

With ngClass, you can mix multiple CSS classes, toggling them individually or creating compound styles:

The hero cards will be highlighted for heroes who can fly and have a different style for heroes who cannot, based on the canFly property.

One more async pipe syntax trick

We’ve covered a few different async pipe syntax tricks earlier in this newsletter, as well as why it’s important to use the async pipe to automate your subscriptions/unsubcriptions from Observables.

Today, let’s see another interesting syntax that can be very helpful when a template has multiple subscriptions, such as:

Even if using ng-container, as we saw earlier this week, is helpful, it would be even better to have just one place where both subscriptions happen.

We can simplify the above by creating a new object that has one property for each Observable value as follows:

That way, all our async subscriptions are in one place, and the rest of our HTML template is much more readable.

New control flow RFC

One of the major announcements on day 1 of ng-conf was the control flow request for comments (RFC).

We’re all familiar with ngFor, ngIf, ngSwitch, and their syntaxes can get tricky at times.

Now what if ngIf was replaced with:

And what if the new syntax supported much more than ngIf, such as else if and even readable else cases:

The goal of the Angular team is to introduce syntaxes that are closer to regular Javascript and remove the need for these structural directives.

for loops would look like this and even support a empty template. All current ngFor local variables would be available automatically with no need for variable aliasing, too:

Finally, ngSwitch would become the following:

Angular CLI would perform the syntax updates throughout your Angular code, so there is no need to worry about rewriting those templates. You can find all the reasons why the Angular team decided on these syntaxes compared to other options in the RFC. You’re, of course, welcome to add your comments and suggestions to the list.

ngFor local variables

We use the ngFor directive so often that it’s easy to forget or even ignore some of its most powerful features.

For instance, it’s fairly common to access the index of an item in the array we’re working with, but there are five more local variables that can be used:

  • index: number: The index of the current item in the iterable.
  • count: number: The length of the iterable.
  • first: boolean: True when the item is the first item in the iterable.
  • last: boolean: True when the item is the last item in the iterable.
  • even: boolean: True when the item has an even index in the iterable.
  • odd: boolean: True when the item has an odd index in the iterable.

The syntax to use those local variables is as follows – and you can use as many as you want in a single ngFor directive like so:

Using a loading template with ngrxLet

A while back, I wrote about how ngrxLet is an improved version of the async pipe. I also covered how to use skeleton loaders with Angular.

Today, let’s look at how we can use these two tools to display a “loading” template while an observable is waiting for data.

As a reminder, here is how ngrxLet can be used to track different observable events:

In the above code snippet, we receive the values emitted by the number$ observable in a variable n. We would receive any error in a variable e. We would receive the completion status (true or false) in a variable c.

Here is how we can pass a custom loading template to ngrxLet using a template reference variable:

Of course, the loading template can be customized with anything you want, including a skeleton loader or an animated gif image. That feature is called a suspense template, and an observable is in a suspense state until it emits its first event (next, error, or complete as covered here).

HostBinding and HostListener

A few months back, I suggested that Angular developers don’t use enough directives and use too many components. This is because components quickly become second nature when writing Angular code, while directives are less common and, as a result, can feel more complex at first.

The critical difference between components and directives is that components have an HTML template, and directives don’t. That lack of a template can be slightly uncomfortable at first unless you realize that you still have access to HTML attribute bindings but in a different manner.

For instance, let’s consider the following component template:

Those two bindings used in a directive would become:

In other words, when you see a binding with [] in a component, @HostBinding() does the same thing in a directive.

For example: [id]="testId" in a component template becomes @HostBinding("id") testId; in a directive class.

The same goes for event listeners. This component (click) binding:

Becomes the following in a directive:

As a recap: [] become @HostBinding and () become @HostListener. Those are the same thing. That’s it. No template is needed. For a real-life example of a custom directive, feel free to take a look at this tutorial of mine.

How to create your own two-way data binding with Angular?

If you’ve ever used [(ngModel)] with Angular, you know what two-way data binding is. The idea is to have a variable that works simultaneously as an Input and an Output.

In today’s post, we will see how to implement such a two-way data binding on our own so that we can use the [()] syntax on any of our component properties, such as message in the following code:

Before we get into this tutorial, I want to tease that signal-based components will have such two-way data bindings available out of the box with the following syntax – using a model() function instead of the @Input and @Output decorators we’re used to:

Note that the above feature will not be a part of the initial developer preview of Angular Signals coming out in less than two weeks with Angular 16. However, it might be available in developer preview in six months with Angular 17.

In any case, here is the link to my custom two-way data binding tutorial and a code example in action on Stackblitz.