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.
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.
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.
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.
Here is an example of code I see way too often when people submit their code to our Angular certification exam:
While I could almost live with the above code, the following example makes me angry (especially because I tell people NOT to do that in bold uppercase characters in my instructions):
What’s the problem with that code? It uses any, and any is dangerous. It isn’t good because it turns off type safety. It makes your code less safe; it removes type information, it makes it less maintainable. It’s excruciating when we know that the HttpClient is nice enough to let us specify the type of the data we’re going to get as a response:
Of course, this type of information does not guarantee that the server is going to return data of that shape, so we have to make sure the server is indeed returning that exact type of data.
But the thing is, once you add that type to your HTTP request, you can (should I say, you must) do the following:
And this is important because when you subscribe to that Observable, Typescript knows what kind of data you receive:
And that is why we use Typescript. Using the above syntax enables autocomplete in your IDE; it brings type safety so you can’t make typos. There are only benefits to using it.
Yesterday, we covered ng-template and touched on different scenarios when it makes sense to use ng-template. Let’s now introduce a close relative of ng-template called ng-container.
There are a lot of similarities between those two elements, which can both be used to use structural directives such as ngIf or ngFor, with the bonus that ng-container can be used with the shorthand syntax of those directives:
One thing you probably noticed as an Angular developer is that we can’t use two structural directives on the same element:
In this scenario, using ng-container is the perfect way to use both directives without adding any HTML to the DOM, as ng-container, just like ng-template, doesn’t create new DOM elements:
Another use for ng-container is to become the host of a ng-template, similar to the way that a router-outlet is the host of routed components:
Such templates can be passed from a parent component using @Input and let the child component decide when to display which template, which is very powerful:
This makes our services the best place to store data that can be shared between multiple different components. Such services can use BehaviorSubjects or Signals to cache that data and replay the last value automatically to any new subscriber (component, directive, pipe, service, etc.).
Here is an example using a signal to store a value and expose it in a read-only fashion:
The lifecycle of an Angular application is something that many aspiring Angular developers struggle with. People often ask me questions such as:
How long does this component/service/directive stay in memory?
How do I save the data before I navigate to the next page/view/component?
What happens if I open that same app in another browser tab?
Here is how to think about it:
When we open an app in a browser tab, we’re booting an Angular application in a self-contained memory space, similar to a virtual machine.
Closing that tab is equivalent to killing the application, freeing any memory associated with it, just like when you close a desktop app in your machine’s operating system.
In Google Chrome, there’s even a task manager where you can see the memory footprint and CPU usage of your tabs and browser extensions – they’re just like independent desktop apps:
From an Angular perspective, a component gets loaded in memory whenever displayed on the screen. That’s when its class is instantiated.
Suppose the component gets removed from the screen (by navigating to a different component or removing it with a ngIf directive, for instance). In that case, the component is destroyed, and all of its memory state is gone. The same goes for directives and pipes: They get created when used by a component template and destroyed when that component gets destroyed.
Services are different, though. A service is created by Angular when a component needs it for the first time. Then, that instance remains unique and shared between all components that inject such service. A service doesn’t get destroyed: It remains in memory as long as your app is open and you don’t close your browser or tab.
This answers our three initial questions:
How long does this component/service/directive stay in memory? Components stay as long as they’re in the DOM. Services stay as long as the app is open.
How do I save the data before I navigate to the next page/view/component? Not if you save it in a service
What happens if I open that same app in another browser tab? You create another separate instance of everything: Components, services, etc. Both instances are independent and do not share any data or memory space.