Published on

Best ways to use ElementRefs in Angular

Ever wondered what ElementRefs are? Well here is it: they are wrappers around native elements inside templates in Angular. But what about how to use them? And what are their pros and cons?

Well, in this blog post we'll go over what Angular ElementRefs are, how to use them effectively, go over their pros and cons and much more. So without further ado let's jump right in!

First for some humor!

Figure 1: First for some humor!

What are ElementRefs in Angular?

ElementRefs are built-in Angular classes that allows us to wrap HTML elements, rendered in the browser, and reference them in the component from where it is rendered.

Now you might be wondering: What does it mean to wrap HTML elements? Well, it simply means to literally enclose the HTML element so that it can be accessed in the component file. Keep in mind, the only way to access the HTML element is through the .nativeElement field of the plain JavaScript object that Angular uses to encapsulate the HTML element.

Example of using ElementRefs in Angular

Now for an example of how to use ElementRefs in Angular!

Let's say we have a component called HomeComponent and it's typescript file has the following code:

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})


export class HomeComponent implements AfterViewInit {

  @ViewChild("homeBtn") homeBtn!: ElementRef;

  constructor(private elementRef: ElementRef){
  }

  ngAfterViewInit(){
    this.homeBtn.nativeElement.innerHTML = "Click here to go home!";
  }
}


Now let's go an explanation for the code above:

  • We are creating a Home component that implements from the AfterViewInit interface. Doing so allows us to call the ngAfterViewInit() method
  • The ngAfterViewInit() method is a Angular life cycle hook that is called after the component's view has its completed initialization
  • Inside the ngAfterViewInit() method we use the nativeElement field on the homeBtn ElementRef to set the innerHTML field to a specified string. As a result, the home button's text changes to match the specified string in the DOM
  • The ! operator is the non-null assertion operator, which serves the purpose of telling Angular not to throw errors regarding the homeBtn variable being null or undefined

Now in order to display the home button in the browser we need to add the following code to the Home component's template file(home.component.ts):

<button #homeBtn><button>

And finally visit the browser on whatever port your Angular application is running locally on to see the button:

Button with the assigned text

Figure 2: Button with the assigned text

Manipulating DOM elements using ElementRefs

Now, let's say you want to change the background color of the button rendered in the previous example. Accomplishing this is very easy with the Renderer2 Angular class.

All we need to do is make the following additions to our home.component.ts file:

import { AfterViewInit, Component, ElementRef, Renderer2, ViewChild } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements AfterViewInit {

  @ViewChild("homeBtn") homeBtn!: ElementRef;

  constructor(private elementRef: ElementRef, private renderer: Renderer2){
  }

  ngAfterViewInit(){
    this.homeBtn.nativeElement.innerHTML = "Click here to go home!";
    this.renderer.setStyle(this.homeBtn.nativeElement, "background-color", "green");
  }
}

And now if we visit the same page on our browser, we see the button's background color changed to green:

Button background color has changed to green

Figure 3: Button background color has changed to green

So as you just saw, the setStyle() method in the renderer2 class is just the tip of the iceberg when it comes to DOM manipulation, with other rendering methods being setText(), setAttribute(), and setProperty() and more...

Security Concerns regarding ElementRefs

While ElementRefs allow for a great deal of functionality and accessibility, they do have their downsides.

The most pressing issue with ElementRefs are that they make your Angular application more vulnerable to XSS(Cross Site Scripting) attacks. This is because when using ElementRefs, the DOM-changing logic gets inserted into the DOM by skipping the Angular sanitation mechanism(provided by DomSanitizer from @angular/platform-browser) . The act of being able to bypass the Angular sanitation checks means that data added to the DOM will not be inspected for malicious content prior to it's insertion.

Therefore, it is recommended that you use template and data binding as the preferred means of DOM manipulation and that you only rely on ElementRefs as a last resort.

If you want to learn more about the security risks involved with ElementRefs, just visit their official Angular documentation page.

Conclusion

In conclusion, ElementRefs have their pros and their cons and whether or not to use them is entirely context dependent, as with many other tools and technologies in Web Development.

Well that's it for this post! Thanks for following along in this article and if you have any questions or concerns please feel free to post a comment in this post and I will get back to you if I find time.

If you found this article helpful please share it and make sure to follow me on Twitter and GitHub, connect with me on LinkedIn, subscribe to my YouTube channel.