[Angular] Why using ElementRef to manipulate DOM is no more a good idea!

Sushant Makin
3 min readJan 5, 2022
Photo by Caspar Camille Rubin on Unsplash

One of the benefits that frameworks like Angular & React provide us over the regular HTML-JS solutions is an easier, better & faster DOM Manipulation. DOM is basically an API that is used to interface the document with. If you want to change any HTML element on the page, you can interact with the DOM API.

Since the launch of Angular 2, DOM manipulation has been pretty straightforward. We can directly access any HTML element using ElementRef provided by @angular/core . One of the most commonly used ways is via a directive, like this:

You will see that the above would work well and would change the font-weight of the element to bold. This is cool! But surprisingly, this isn’t a good approach as:

  • Permitting direct access to the DOM can make the application more vulnerable to XSS attacks. This is because DOM APIs do not sanitize the data. Use this only when you have no option left to access the DOM element.
  • Angular keeps the Component & the HTML view in Sync using Templates, data binding, change detection, etc. All of these are bypassed when we update the DOM Directly.
  • If we rely on direct DOM access, it creates tight coupling between the application and the rendering layers, which will make it impossible to separate the two and deploy the application into a web worker.

Renderer2: The Safer & Better way of DOM Manipulation

The Renderer2 class is an abstraction provided by Angular in the form of a service that allows us to manipulate elements of the app without having to touch the DOM directly. This is the recommended approach because it then makes it easier to develop apps that can be rendered in environments that don’t have DOM access, like on the server (SSR), in a web worker, or on native mobile.

Let’s modify our above example now by using Renderer2 and make our app safer.

This will have the same result as the first sample, but this is a far better and secure approach. Renderer is pretty useful for common use cases, and also for complex DOM manipulation.

There are plenty of inbuild methods available that let us manipulate the DOM. A few of the most common ones are:

Setting & Removing Styles (setStyle & removeStyle)

Use the setStyle & RemoveStyle to add or remove the styles. It accepts four arguments.

  1. Element to which we want to apply the style.
  2. The name of the styles.
  3. The value of the style.
  4. The flags for style variations
setStyle(el: any, style: string, value: any, flags?: RendererStyleFlags2): voidremoveStyle(el: any, style: string, flags?: RendererStyleFlags2): void

Adding / Removing CSS Classes (addClass & removeClass)

Use the methods addClass / removeClass to add or remove classes.

addClass(el: any, name: string): voidremoveClass(el: any, name: string): void

Setting or Remove Attributes (setAttribute & removeAttribute)

We can add remove attributes using the setAttribute & removeAttribute

setAttribute(el: any, name: string, value: string, namespace?: string): voidremoveAttribute(el: any, name: string, namespace?: string): void

More details around Renderer2 can be referenced from the official Angular documentation.

--

--

Sushant Makin

Software Architect at Entain | Trying to make web development simpler & faster | Twitter: @sushantmakin