Mastering DOM Manipulation in Angular with Renderer2: A Complete Guide – Part 1



This content originally appeared on DEV Community and was authored by vetriselvan Panneerselvam

Hey devs,

We’ve all worked with JavaScript DOM manipulation at some point. But have you ever wondered how to properly handle DOM manipulation in an Angular application? The answer is simple: use Renderer2! Let’s explore how Renderer2 helps us manage the DOM the Angular way.

What is Renderer2?

Renderer2 is a service provided by Angular that allows you to create and update DOM elements in a safe and platform-independent manner.

How to Use Renderer2

You can inject Renderer2 into your component or service like this:

private renderer: Renderer2 = inject(Renderer2);

APIs in Renderer2

Let’s start by creating a div element and appending it to a component dynamically using Renderer2.

createElement

The createElement method is used to create a new element in the DOM. After creating the element, you need to append it to the DOM; otherwise, it won’t be visible.

Syntax:

createElement(name, namespace);
Parameter Description
name An identifying name for the new element, unique within the namespace.
namespace The namespace for the new element.

Example:

const divElement = this.renderer.createElement("div");

appendChild

The appendChild method is used to append an element to the DOM. First, get the parent element, then append the child element to it. In this example, we append the div element to the component’s root element, so the new element will appear at the bottom of the component’s DOM.

Syntax:

appendChild(parent: any, newChild: any)
Parameter Description
parent The parent node.
newChild The new child node.

Example:

this.renderer.appendChild(this.el.nativeElement, divElement);

This will add an empty div to the DOM. You can see it by inspecting the element in your browser’s developer tools.

Now we are goign to define a property to the div. let try adding some content to that div element we created . that will help us to see the div we added in the DOM.

setProperty

The setProperty method is used to set a property of an element.

Syntax:

setProperty(el: any, name: string, value: any)

setProperty is used to set the property of the element. you can set different properties of the element. like innerHTML, innerText, value, etc.

Example:

this.renderer.setProperty(
  divElement,
  "innerHTML",
  "This is a dynamically created div element. Right click on it to see the inspect element."
);

setAttribute

The setAttribute method is used to set the attribute of an element.

Syntax:

setAttribute(el: any, name: string, value: any)
Parameter Description
el The element.
name The name of the attribute.
value The value of the attribute.

Example:

this.renderer.setAttribute(divElement, "class", "dynamic-class");

setStyle

The setStyle method is used to set the style of an element.

Syntax:

setStyle(el: any, style: string, value: any, flags?: RendererStyleFlags2): void
Parameter Description
el The element.
style The name of the style.
value The value of the style.
flags The flags for the style.

Example:

this.renderer.setStyle(divElement, "color", "red");


Now we can see the element in the screen with the above text. Let go one more step ahead. In case the user want to highlight the element when mouseover. you can simply listen the dom events as well.

listern

The listern method is used to listern the dom events of an element.

Syntax:

listen(target: "window" | "document" | "body" | any, eventName: string, callback: (event: any) => boolean | void, options?: ListenerOptions): () => void
Parameter Description
target The context in which to listen for events. Can be the entire window or document, the body of the document, or a specific DOM element.
eventName The event to listen for.
callback A handler function to invoke when the event occurs.
options Options that configure how the event listener is bound.

Example:

this.renderer.listen(divElement, "mouseover", () => {
  console.log("div mouseover");
  this.renderer.setStyle(divElement, "color", "green");
});

createComment

The createComment is used to create a commended html content to the dom of the host element .

Parameter Description
value The comment text

Example:

this.renderer.createComment("This is a dynamically created comment element.");


Now if you inspect the element you can see the commment text in the dom

createText

The createText callback used to create a text to the dom of the host element .

Parameter Description
value The comment text

Example:

const textElement = this.renderer.createText(
  "This is a dynamically created text element."
);
this.renderer.appendChild(this.parent?.nativeElement, textElement);


Same like create element you need to append the text element to make sure it is added to the dom

insertBefore

Imagine a case where we need to insert a element before the some element or to insert a child at a given position of the parent node in the host element dom.

Parameter Description
parent The parent node
newChild The new child nodes
refChild The existing child node before which newChild is inserted.
isMove Optional argument which signifies if the current insertBefore is a result of a move. Animation uses this information to trigger move animations. In the past the Animation would always assume that any insertBefore is a move. This is not strictly true because with runtime i18n it is possible to invoke insertBefore as a result of i18n and it should not trigger an animation move.

Example:

const divElement = this.renderer.createElement("div");

this.renderer.setProperty(
  divElement,
  "innerHTML",
  "This is a dynamically created div element. Right click on it to see the inspect element."
);

this.renderer.setStyle(divElement, "color", "red");
this.renderer.setAttribute(divElement, "class", "dynamic-element");
this.renderer.appendChild(this.parent?.nativeElement, divElement);

const buttonElement = this.renderer.createElement("button");
this.renderer.setProperty(buttonElement, "innerText", "Click me");
this.renderer.insertBefore(
  this.parent?.nativeElement,
  buttonElement,
  divElement
);


In the above example you can see that i create a div element with some attribute and the append the child node (div node ) to the parent node.
After that i created a button element and insert it before the div element . Now in the screen you can see the position of the button is above the div element.

removeChild

We all need to handle the case to dynamically remove the node from the dom. Just example based on the login user we need to show and hide the element . For those case you can use the removechild callback.

Parameter Description
parent The parent node.
oldChild The child node to remove.
isHostElement Optionally signal to the renderer whether this element is a host element or not

Example :


   const textElement = this.renderer.createText(
      "This is a dynamically created text element."
    );
    this.renderer.appendChild(this.parent?.nativeElement, textElement);

  setTimeout(() => {
      this.renderer.removeChild(this.parent?.nativeElement, textElement);
    }, 5000);

We created a text elemnt and append that to the dom and after 5s we are removing the node from the parent node using removechild callback

selectRootElement

Implement this callback to prepare an element to be bootstrapped as a root element, and return the element instance.

Parameter Description
selectorOrNode The DOM element.
preserveContent Whether the contents of the root element should be preserved, or cleared upon bootstrap (default behavior). Use with ViewEncapsulation.ShadowDom to allow simple native content projection via elements.

Example :

    const rootElement = this.renderer.selectRootElement('app-root',true);
    console.log(rootElement);

you can select the element by passing the selector name or id or css class or node of the element . Make sure with preserveContent: false, as it clears the contents of the selected element

📁 Want the Full Code?

We’ve only scratched the surface. Watch out for Part 2, coming soon!

💬 Got questions or use cases you want to share? Drop a comment below! Let’s discuss more Angular magic. ✨

✍ Author: Vetriselvan

👨‍💻 Frontend Developer | 💡 Code Enthusiast | 📚 Lifelong Learner | ✍ Tech Blogger | 🌍 Freelance Developer


This content originally appeared on DEV Community and was authored by vetriselvan Panneerselvam