Localized pricing now available for all courses and exams

Subscribers of this newsletter are located on all continents worldwide. Still, I’m based in one of the most expensive states (California) of one of the most expensive countries (USA) in the world, which means that sometimes, people complain about the prices of my services.

Good news! I decided to apply purchase parity pricing (PPP) on all my courses and certification exams, which also applies to the upcoming Angular Accelerator program.

If you live in an eligible country and go to the purchase page of any of those courses, a banner will appear with a coupon code that gives you a discount based on your country’s economic situation.

Of course, I can also make further exceptions on a case-by-case basis, so feel free to email me if you’re in a challenging situation and need financial assistance, or if the banner doesn’t show up for you.

RxJs trick: Emitting from an Observable into a Subject

Using a Subject to emit data is something we do a lot in Angular applications, and more often than not, what we try to emit is the result of an HTTP request, such as:

While the above works perfectly well, it’s important to know that the subscribe method of an Observable takes either a function as a parameter (which is what I’ve done in the previous example) or an object that implements the Observer interface. We touched on that interface earlier to illustrate exciting things we could do with the tap operator.

The thing is that Subjects implement that interface, so we can simplify our earlier code into:

This isn’t just a syntax improvement, as writing less functions results in better overall Javascript performance. Less code to ship = less code to download = less code to interpret and store in memory for the browser = faster user experience. You can see a code example here on Stackblitz.

How to create custom form controls with Angular?

When working with lots of forms, you’ll likely use similar controls repeatedly: A country selection dropdown, a state selection dropdown, a date-range picker with specific constraints, etc.

Instead of duplicating our code, which is never a good idea, Angular allows us to create custom form controls that integrate with Angular’s form validation mechanism.

This feature requires our custom control component to implement an interface called ControlValueAccessor that has the following methods:

I have a detailed tutorial and code example if you want to dive deeper into that topic.

It’s also worth noting that you don’t have to start from scratch when implementing a control value accessor. Angular has a DefaultValueAccessor directive (the one used by FormControl, NgModel, etc., in Angular forms) that can be invoked with the selector ngDefaultControl, and there are a few more options available, such as the SelectControlValueAccessor.

How to run code in an injection context?

Yesterday, I introduced an injection context, and we saw a few locations where we could inject dependencies. This can be limiting in scenarios where we call a method that creates and returns an Observable outside of an injection context, as we can’t always initialize observables in a constructor. Does that mean we cannot use the takeUntilDestroyed operator in those scenarios?

No, because we can store our injector for later use using the following approach:

The key is to use the runInInjectionContext function and pass the injector as a parameter.

For the takeUntilDestroyed operator, we can inject a DestroyRef in our injection context and then use it as a parameter whenever we need that operator:

Problem solved! We can use all these tools from the framework in any place we want, thanks to EnvironmentInjector and DestroyRef.

What’s an injection context?

In the past few months, the introduction of the inject() function and the takeUntilDestroyed operator shared something important: While these features are based on functions, these functions have to run within an Angular injection context, or you’ll get errors from the framework.

That’s because Angular relies on dependency injection for almost everything. As a result, it’s helpful to know what is an injection context.

The most apparent injection contexts are these:

  • Constructor of an “Angular class” such as services, components, directives, pipes, etc.
  • In the initializer for fields of such classes.

Here is an example of what is and isn’t an injection context:

Other places are injection contexts:

  • In the factory function specified for useFactory of a Provider or an @Injectable.
  • In the factory function specified for an InjectionToken.
  • Within a stack frame that is run in an injection context.

In other words, this is when you’re configuring a module or dependency injection. The most common examples are related to the router – guards, resolvers, and such are all in the injection context, so we can inject dependencies there:

Pluralizing text with the i18nPlural pipe

Pluralizing is as natural in human language as it is painful to handle programmatically. Let’s say we want to address the following scenarios in an app that displays the number of posts:

  • If we have zero, display “No post.”
  • If we have one, display “1 post.”
  • If we have more than one, say 5, display “5 posts.”

We could use a combination of ngIf / else scenarios to handle this, but it would get ugly quickly. The upcoming control flow API would help, but it’s not available yet.

Instead, we can use the i18nPlural pipe as follows:

The above syntax determines what to display for each scenario: 0,1 or any other value. You can find an example here 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.

How to use HTTP interceptors?

Angular HTTP interceptors can intercept and modify HTTP requests and responses. They can be used for a variety of purposes, such as:

  • Logging the details of HTTP requests and responses, such as the URL, headers, and body. This can be helpful for debugging and troubleshooting.
  • Authentication: Authenticate requests before they are sent to the server by adding custom headers to the HTTP request.
  • Caching: Interceptors can be used to cache HTTP responses, improving performance.
  • Error handling: Handle errors that occur during HTTP requests. This can help provide feedback to the user when the connection with the server is lost.

To create an Angular HTTP interceptor, you must create a class that implements the HttpInterceptor interface. The intercept() method of this interface is called whenever an HTTP request is made.

This method allows you to inspect and modify the request before sending it to the server.

Here is an example of an Angular HTTP interceptor that logs the details of HTTP requests:

To use an Angular HTTP interceptor, you need to register it. You can do this by adding the interceptor to the providers array of your AppModule as follows:

Once you have registered an HTTP interceptor, it will be called whenever an HTTP request is made.

You can see a complete example of how to intercept a request to add an auth token in this tutorial. The tutorial also covers how to intercept a response and change it. A complete example of such an interceptor can be found on Stackblitz.

Browser dev tools for LocalStorage

Last week, I introduced localStorage and sessionStorage. I also suggested a few options to get notifications when such storage gets updated.

Today, I will cover how we can visualize and debug storage data. In Google Chrome, open the dev tools (right-click on the webpage, then “inspect” or press Ctrl + Shift + I).

Once the dev tools panel shows up, click on the “Application” tab:

You can select Local Storage or Session Storage on the left-hand side. This shows you the contents of those storages on the right-hand side in key-value pairs. Storage is by domain, so using those tools on a different website would show you different data.

If an object is stored as a JSON string, you can click on the key-value row, and Chrome shows a collapsible version of that Javascript object at the bottom of the screen, making it easy to explore complex objects:

There are two buttons in the top right corner of that same panel. One allows you to clear the entire storage for the current domain, while the second one (the X) clears the currently selected key-value pair:

You can edit a key or value by double-clicking on the corresponding cell in the right panel’s table. This makes testing different values, resetting a cache, or debugging specific scenarios easy.

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.