Typescript visibility modifiers

Angular is mostly about Typescript classes, and Typescript classes have modifiers that alter the visibility of class members: public, protected, private, and readonly. Here is what you need to know about them.

Everything is public by default

If you don’t use a modifier on a class member, it is public by default. Any other class can see and use that member and change its value:

private means that the member isn’t visible outside of the class (including a component’s HTML template)

private is a way to enforce that other classes cannot access a member of your class. Used in a component, this indicates that we do not want that property to be used in the component’s HTML template. In a service, this suggests that we don’t want other components/services to see that member:

protected is in-between public and private. It makes the member accessible in a component’s template without making it fully public.

In the following example, our component property date is invisible from other Angular code in our app, but our HTML template can use it:

Best practice – My recommendation

If you want to stick to simple rules that make sense and are the safest, here’s what you can do:

  1. Make every member private by default
  2. If the member is needed in the template of a component, make it protected
  3. If the member is meant to be fully public, go with public

Tomorrow, I’ll add a couple more suggestions by introducing the readonly modifier. Stay tuned!

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.

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.

What is ng-container?

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:

You can find a complete code example of such a feature in this Stackblitz and a more in-depth tutorial here if you want to try it.

Using setters for better @Input

When using @Input in our components, we can implement ngOnChanges to be notified whenever an input value has changed:

The above code works and would run whenever id or name are updated by the parent component. The problem is that this syntax can quickly become heavy when there are several @Inputs in your component.

Instead, we can do this:

Instead of using @Input() on a class property, we can use it on an ES6 setter function. The benefit of the setter syntax is that it makes it obvious what kind of code we’re running when the @Input value is set. No more ngOnChanges needed.

How to pass multiple pieces of content from one component to another?

Yesterday, we saw that we could use content projection to pass an HTML template from one component to another. But what if we want to pass multiple different templates? We can use multi-slot content projection.

Here’s what we want to achieve:

In our reusable dialog component, we will have multiple ng-content elements. Each ng-content will have a specific query selecting a template to render:

These queries use the CSS selector syntax. In the above example, we’re using [], which means we are selecting HTML attribute names. As a result, our parent component will pass two distinct templates, one for the body and one for the footer, using the following syntax:

You can see an example of such code in action on Stackblitz.

Passing custom content to a component with content projection

If you’re creating a component library or working on components meant to be as generic and reusable as possible, then content projection should be a major part of your Angular toolkit.

Let’s take the example of a pop-up window/dialog component:

The main idea of content projection is that the parent component (most likely a container component) knows about the current use case of our reusable presentation component and can pass custom HTML to it. Such content is passed in the content section of the component, which is the body of the HTML element – what we have between the opening and the closing tag:

Angular projects that content into the template of the child component. We can set the destination of that projection by using an ng-content element in the template of the reusable component as follows:

Content projection is like cutting and pasting some content from one component to another. You can see the full code example here on Stackblitz.

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).

Skeleton loaders with Angular

Skeleton loaders are grey-shaded shapes that indicate when a part of the screen is loading. Here is an example of skeleton loaders for Facebook:

ngx-skeleton-loader is a small component library that does just that. It gives us access to different skeleton loaders ready to be used in our applications:

What’s nice about that library is that we can customize different aspects of the skeletons, such as animations and colors. You can find some live examples here.

If you want to explore skeleton loaders for your application, feel free to look at my popular tutorial: How to use a skeleton loader with Angular?

The tutorial has several code examples that can be used as-is.