The ins and outs of Angular — [ngClass]

Ryan Hoffnan
ITNEXT
Published in
3 min readFeb 17, 2021

--

Today I will deep dive into another commonly used Angular directive called NgClass, like others (ngIf, ngFor, and ngStyle), we use them without a second thought of what black magic is going under the hood. Let's check it out.

All valid options to pass to the ngClass directive

ngClass, similar to ngIf and ngFor, is actually a setter that takes the data given to it and starts to build the class list for the element it is placed on, with the help of ElementRef (a reference to the HTML element we are currently on) and Renderer2 (Which is a wrapper of browser API functions for DOM manipulation).

NgClass setter

The first step of the ngClass function does is to remove any existing classes that could have been set from a previous iteration of data of the directive, and assign the “initial” classes which were under the class attribute. when using ngClass the class attribute is no longer the attribute we know from vanilla JS, but an Input, part of the ngClass directive.
We can see the use of the term “klass” in the code. which is a reference to the original class attribute which can have a list of strings as classes

remove and add classes

Removing and adding classes are essentially the same logic, it iterates over the array of strings or objects to add or remove the appropriate classes from our HTML element. (a lot of redundant code, in my opinion, building a praser to unify the schematics of strings to objects would make it cleaner).
Notice that Angular does its best to keep our UI safe with type checks, checking if isArray or is an instance of a Set for example. Angular does not leave anything to chance. Even if redundant it's explicit.

The function _toggleClass is simple as it gets, it receives the class string and a boolean value which indicates if it should toggle it on or off (i.e remove or add the class through another Angular black magic class, the Renderer2).

After removing and adding the updated classes, our directive does one more thing, adds a listener of sorts into the corresponding variable to see if changes have occurred. or to be more precise what changes have occurred (added/removed/updated).

_rawClass = the class we passed as parameters to the [ngClass]

After all the setup has been set, the directive uses a directive lifecycle function called ngDoCheck (implements DoCheck).
ngDoCheck runs whenever our Angular application runs its change detection mechanism. When ngDoCheck runs, it validates its own inner change differ. If there are changes from the previous iteration, ngClass updates the classes of the element correctly with the new class list or object given.

As we can see the directive does a lot of “tricky” things to protect our code but yet provide us with the ability to not change how we write our code. the fact that when ngClass is present, the class attribute is no longer an attribute, but an Angular Input is extremely smart and intuitive.

Below is a flow diagram to show what happens in the ngClass directive in simple terms.

A diagram of ngClass flow

Next up — Angular router. If you want me to go over some other subject in Angular please contact me.

--

--