ng-conf 2024 early bird pricing ends soon

I’ve already mentioned that ng-conf is the only conference I wouldn’t miss for any reason, and ng-conf 2024 will be no exception to that rule. I want to bring your attention to the fact that the conference is scheduled early next year: March 20-21, 2024 (it was in June 2023).

Early bird pricing ends on December 1st, and prices will go up by $100, so if you plan on attending, now is the time to score the best-priced tickets. If you can’t attend in person, there is an option to attend remotely as well, and the price seems to be the same, but it includes an additional pre-conference workshop.

In any case, I’ll be there (on stage or not, I don’t know yet), so if you come over to Salt Lake City, feel free to say hi.

routerLinkActive directive

Have you ever wondered how to highlight a specific HTML element, such as a link or a button, when a particular URL is selected? Something similar to this:

The good news is that there is a specific directive for this called routerLinkActive. Here is how you can use it:

The value set to routerLinkActive is the name of a CSS class (or several CSS classes) that gets applied to the HTML element when the current URL path matches the path of the routerLink directive on that same element. In other words, if the path is page1, then the button element has an active class applied to it.

As a result, all I did to style the above example was add that CSS class definition to my global CSS file:

And that’s it! Note that the directive supports several other options documented here:

You can see my example in action on Stackblitz here.

ShareReplay Code Challenge #1 Solution

What was wrong with yesterday’s code example? Here it is as a reminder:

Since the developer used the shareReplay operator, the intent was to cache the result of the HTTP request so that we do not make that request repeatedly.

The problem is that if several components call the getData() method, they all get a brand new Observable since the method returns a new request every time, which defeats the purpose of using shareReplay.

How can we fix this? By creating the Observable once then sharing the results in subsequent calls to getData():

Here’s another way to do it, perhaps even more readable:

Why do these solutions work? DataService is a singleton, which means all components use the same instance of DataService. As a result, any property of DataService (such as cache$) is the same for all components that access it.

Another critical thing to note is that HTTP requests are cold observables, which means they only fire when a subscriber subscribes to them.

Code Challenge #1: shareReplay

One of the cool things about teaching Angular, running an Angular certification program, and interacting with hundreds of developers (and code bases) all around the world is that I get to see a lot of good ideas but also a lot of repeated mistakes.

Today, I want to share a small code challenge inspired by repeatedly seen examples over the past few weeks, so you can learn from these examples and won’t make these mistakes in the future.

Here is an example of service for you to look at:

The challenge I have for you is to answer these questions:

  1. What do you think is the requirement behind the code in that service? Why use the shareReplay operator?
  2. Assuming that three different components call the getData() method in their constructor to get an Observable and subscribe to it using the async pipe, how many requests will be made to the API server?
  3. Is the original requirement met or not? How to fix that code if it isn’t working correctly?

I’ll give you these answers tomorrow. In the meantime, feel free to reply with your own answers if you want.

Short video recaps of Angular 17 features

In case you missed it, the Angular team has created a playlist of all Angular 17 features in (mostly) short videos with highlights and examples. Those are, of course, similar to the content covered in the newsletter last week, but here are some direct links to the shortest and most interesting videos:

Remember that it’s essential to use a recent version of Angular and that upgrading often is a lot easier than delaying upgrades repeatedly.

Vote for the future of this newsletter in 2024

There’s only a month and a half left in 2023, and my goal is to keep publishing daily updates till the end of the year, except on public US holidays (such as Thanksgiving and Black Friday later this week).

In 2024, I’m thinking about slowing the cadence down to weekly or even monthly emails, and I would love to hear your input on that. As you can imagine, publishing content every day is quite a big task, and I’ve done it even when on vacation so far this year. I would prepare all posts before traveling – which means a lot more work upfront.

The only way I could keep doing daily posts was if there was some sort of paid subscription model, but I’m not sure if that option would be popular.

As a result, I’d appreciate your feedback and input on what you’d like to see in 2024 and if a daily newsletter with a paid subscription is something you’d be OK with or not at all. A weekly or monthly option would remain free, of course.

Feel free to hit reply and let me know.

Angular 17: Signals, Server-side rendering, and Standalone

We’re not done with Angular 17 updates! Here are a few more updates on Signals, Standalone, and Server-side rendering.

Signals

Signals have graduated from developer preview and are now officially part of the framework, except the effect function that is still being tweaked by the Angular team. A big step for Angular Signals.

Standalone

With Angular 17, a new Angular app is generated with standalone components by default. You can upgrade your Angular CLI to test that out, and if you don’t want to use standalone by default and your new apps, this feature can be turned off in angular.json with the following config:

   "projects": {
    "my-app": {
      "schematics": {
        "@schematics/angular:component": {
          "standalone": false
        }
     Code language: JavaScript (javascript)

Server-side rendering

With Angular 17, you can create an app that uses server-side rendering with a single command:

ng new --ssr

If you want to add server-side rendering to an existing app, you can run:

ng add @angular/ssr

It’s also possible to pre-render an Angular app using:

ng build --prerender

That way, you don’t need Node.js hosting and can use static, pre-rendered HTML files. I’ll explore this more in the newsletter before the end of the year.

On that same topic of server-side rendering, hydration graduated developer preview, which means an app rendered on the server side won’t rebuild its entire DOM in the browser. Instead, Angular will take over that DOM and re-hydrate it with up-to-date data as needed.

Angular 17: Simplifying style(s)

A major focus of the Angular team over the past two years has been to improve the developer experience by removing some of the common annoyances in the framework (better error messages, for instance). This is often referred to as “quality of life” improvements, and the Angular 17 feature I want to cover today is undoubtedly one of those.

Have you ever wondered why the component decorator always had a styleUrls or styles attribute even when 99.9999% of the time, we need one style URL or CSS style?

Well, I have good news for you! Angular 17 introduced a styleUrl attribute (singular) for a single style file:

And the other styles attribute has more flexibility as well as it now supports a single string or an array of strings, which means all options are available now:

A simple change that makes our life easier!

How to update your Angular CLI?

We touched on many Angular 17 updates so far, and if you want to test those out on a fresh new project, you’ll need to upgrade your Angular CLI to v17.

Here is the most straightforward command to upgrade your global Angular CLI to the latest version:

npm install -g @angular/cli@latest

That’s it! The -g flag indicates we want to install that CLI globally, and the @latest at the end ensures we’re getting the latest stable version.

Angular 17: New devtools injector tree view

Another Angular 17 update is the release of a new DevTools panel called Injector Tree. It’s a good option to visualize both your element hierarchy and injector hierarchy, and it is accessible as a third tab in the Angular DevTools browser extension available for Chrome, Firefox, and Edge:

When we click on that tab, a tree view of all hierarchies shows up on the screen:

For a clearer view, we can check the option “hide framework injectors” to focus on our code:

Clicking on an injector (such as root) shows the list of all injectables/services available in that injector:

This new tab seems to be just getting started, and more information will be added later. Even though the Devtools is a browser extension, the Injector tree tab only works for apps using Angular v17+. I tried an Angular v16 app with no success.