Angular 16 is now available!

Angular 16 is now available! You can watch a quick summary video from the Angular Team (in less than 7 minutes).

We’ve already covered quite a few of the new features in this newsletter:

Other notable features include:

  • Improved server-side rendering with non-destructive hydration: If you’re using Angular Universal, your app can now be refreshed on the client side without re-building the entire DOM (also a developer preview)
  • Angular CLI commands to convert your app to standalone components: ng generate @angular/core:standalone and to create a new standalone app with ng new --standalone
  • Experimental support of Jest (instead of Karma/Jasmine) for unit-testing
  • Support for Typescript 5.0.

The Angular team released a long blog post highlighting these features in more detail. I’ll cover more of these features individually over the following weeks, but for now, I’ll let you upgrade to the latest version with this tutorial.

NG16 Preview: Helpers to convert class guards to functional

As covered a few newsletters ago, Route guards are meant to be functions with Angular 15+. Angular 16 removes the support for class guards.

Does that mean we have to migrate our old class guards manually? Of course not! The Angular team has our back, and the Angular CLI will remove the deprecated interfaces automatically when upgrading to Angular 16 as follows:

Then, if you want to keep your guards as classes, you can do so using a helper function called mapToCanActivate:

Or you can, of course, decide to use a function instead:

Angular 16 Preview: Binding Router Information to Component Inputs

Passing parameters to routes is a frequent task with Angular. Before Angular 16, we had to inject the ActivatedRoute service and retrieve the parameters from that service using the snapshot or params properties.

With Angular 16, we can get those values automatically bound to the component inputs using the following router config:

If you’re using the RouterModule.forRoot() syntax, then enabling component input binding looks like this:

RouterModule.forRoot(routes, {bindToComponentInputs: true});Code language: JavaScript (javascript)

According to the documentation, this option can bind all route data with key-value pairs to component inputs: static or resolved route data, path parameters, matrix parameters, and query parameters.

For instance, assuming we have a URL parameter called id, if we enable the component input binding feature, then all we need in our component is an @Input decorator to receive that value:

What I like about this option is that our components do not need the ActivatedRoute service anymore, meaning they don’t have to be used just as routed components. Instead, they could be used in other scenarios where the id is passed as an HTML attribute, just like any other non-routed component. As a result, our components are more generic and not tied to a single use case.

Angular 16 Preview: Required Inputs

The @Input decorator plays an essential role in the Angular framework as such inputs for presentation components allow us to fine-tune application performance by using the onPush change detection strategy.

Earlier in this newsletter, we also talked about how inputs justified the existence of the ngOnInit lifecycle hook.

Inputs are about to become even better in Angular 16 with the addition of required inputs that would throw a compile-time error when an input for a component/directive is required but not set:

The syntax is easy to remember, too. Angular 16 is scheduled to be released this week, and I’ll be posting more new features of that new version all week long.

The main feature of v16 will be Angular Signals, so I just released a short video course to learn all you need to know about Angular Signals for just $9!

Angular 16 Preview: TakeUntilDestroyed

Angular 16 will be released next week, and this new version will be big. I will cover most of the new features of Angular 16 for the next few days.

One of the simple but handy features shipped with Angular 16 is a new operator for RxJs Observables: takeUntilDestroyed.

We have covered several techniques to automatically unsubscribe from Observables in this newsletter.

takeUntilDestroyed will make all of it easier than ever:

And that’s it! That one operator will take care of automatically unsubscribing from data$ when the component/pipe/directive using it is destroyed.

Signals will be the most significant addition to Angular 16 (as a developer preview – for now), and as a result, I’m about to launch a short course on Signals. If you’re interested in beta-testing that course (for free!), please respond to this email to let me know.

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.

Anti-pattern: Subscription within a subscription

Welcome to this new series on Angular anti-patterns. I intend to cover one anti-pattern per week for a few weeks, starting with one of the most common ones: Subscribing to an Observable within another Observable subscription. Here’s an example where we get a country and then the currency for that country:

Why is this a bad idea? Here are a few reasons:

  • getCurrencyForCountry() is never unsubscribed, which can lead to memory leaks.
  • When the country changes, the Observable that gets the previous country’s currency is not canceled. If that Observable emits again, this.currency will get overwritten.
  • Such nested callbacks are hard to read, and as a result, such code is more challenging to maintain.

Let’s imagine our component template is as follows:

Then in a scenario where getCurrencyForCountry() emits updates values every second, our component would end up displaying the following values, which become wrong very quickly:

You can take a look at that code here.

The solution to avoid such issues is to use the switchMap operator as follows:

The above code works fine because switchMap cancels the previous currency Observable as soon as a new country is emitted from service.getCountries(). No more memory leaks, and our two Observables are always in sync:

Here is a link to that same code example using the switchMap operator.

keyValue pipe

The keyValue pipe turns any object into an array of key-value pairs, which can be helpful for debugging purposes or working with an object with a dynamic shape.

Here’s an example:

In this example, we’re using the keyValue pipe to iterate over the properties of user and display them. The item variable represents each key-value pair in the object, and we’re using the item.key and item.value properties to display the key and value for each item.

As a result, if user is this object:

The component displays:

You can see the above example in action on Stackblitz.

This pipe is part of my collection of 3 Angular pipes everyone should know about, including the async pipe and the json pipe.

RxJs takeUntil and takeWhile operators

Our Rxjs operators of the week are takeUntil and takeWhile. These operators are the opposite of skipWhile covered last week: They let the values from the source Observable pass through until a condition is met.

takeUntil is based on a second Observable and stops emitting values when that second Observable emits for the first time, as illustrated in this marble diagram:

takeWhile is very similar but uses a predicate instead of an Observable to decide when to stop emitting from the source Observable:

The primary use case for takeUntil with Angular is to automate unsubscriptions from Observables, even though I recommend less verbose approaches to automating unsubscriptions, such as using the async pipe :

The above code uses a subject to emit a value when the component gets destroyed, thanks to the ngOnDestroy lifecycle hook. Then, that same subject is used by takeUntil to complete the source Observable.

Here is a different example of takeUntil in action on Stackblitz.

Angular profiler for performance tuning

The Angular dev tools introduced in our previous newsletter include a second tab called Profiler:

The Profiler has a single record button. We can hit it, play with our application, then stop the recording. This turns the UI into a profiler view of what happened during the recording. In the example below, we can see how a click generated a change detection event that impacted several components:

As you can see in the above screenshot, every change detection event is tracked as a bar chart entry. The taller a bar is, the more time it takes to complete that cycle. We can explore which components and directives are impacted for each event and how long it took to re-render that component (in the above example, 0.1 ms).

When facing a performance issue, the Profiler is perfect for identifying the problem’s root cause. For instance, it could highlight that one component is much slower than the others and gets refreshed for no good reason, indicating that a different change detection strategy is needed.

The official documentation showcases all individual features of the Profiler one by one.