A community of developers

Angular

Angular 10 ViewChild, ElementRef & AfterViewInit: Access Child DOM Elements from Parent Component by Example

In this tutorial, we’ll see how to use ElementRef, ViewChild decorator, and AfterViewInit life-cycle event for accessing the DOM by example with Angular 10.

What’s ViewChild and AfterViewInit?

You can use ViewChild if you need to access a child component, directive or a DOM element from an Angular parent component.

The ViewChild decorator is the way you can achieve DOM access in Angular way. ViewChild returns the first element that matches a given component, directive or template reference selector.

You can also have access to multiple children using ViewChildren instead.

We can access the following elements:

  • Angular directives,
  • Native DOM elements: We can access native DOM elements that have a template reference variable,
  • Child components from the parent.

AfterViewInit is a life-cycle hook that gets fired when the view corresponding to the component is completely rendered. This can be used to safely access the variables, directives and child components.

What’s ElementRef?

Although you can access the DOM using native JavaScript APIs in Angular, it’s recommended to use APIs provided by Angular. We can access the DOM elements by using ElementRef available from by @angular/core.

ElementRef allows you to access the native DOM element using the nativeElement property. But you need to be careful when making direct DOM access in Angular.

According to Angular docs ElementRef:

_Use this API as the last resort when direct access to DOM is needed. Permitting direct access to the DOM can make your application more vulnerable to XSS attacks.Carefully review any use of ElementRef in your code. Use templating and data-binding provided by Angular instead. Alternatively you take a look at Rendererwhich provides API that can safely be used even when direct access to native elements is not supported.

Relying on direct DOM access creates tight coupling between your application and rendering layers which will make it impossible to separate the two and deploy your application into a web worker.

Not good. But, there’s an alternative called Renderer2.

Angular 10 ElementRef and ViewChild by Example

Let’s see how to use ElementRef and ViewChild by example.

Accessing Native DOM Elements with Template References

Let’s get started by an example of to access a native DOM elements which has a template reference variable.

Open the src/app/app.component.ts file and update it as follows:

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

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

  name = 'Angular';
  @ViewChild("myimg") elm: ElementRef;

  ngOnInit(){}

  ngAfterViewInit(){
    console.log(this.elm);
  }
}

Next, open the src/app/app.component.html file and update it as follows:

<p>
Hello Angular 10
</p>
<p>
Angular 10 ElementRef by Example
</p>

<img width="560" height="249" #myimg src="https://i.ytimg.com/vi/M9ctBliiq1A/maxresdefault.jpg"/>

Check out the example from
https://stackblitz.com/edit/angular-9-10-elementref-example.

Accessing Child Components from Parent Component

Now that we have seen how to access a native DOM element using ViewChild, ElementRef and ngAfterViewInit let’s how to access child components from their parent.

We can access a child component and call its methods or access its instance variables. Let’s suppose we have a child component with a sayhello method:

sayhello() {
  return 'Hello from the child!';
}

We can then call the method from our parent component class using ViewChild as follows:

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

import { MyChildComponent } from './mychild.component';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
  @ViewChild(MyChildComponent) child: MyChildComponent;
} 

You can call the method using child.sayHello() syntax.

Accessing Angular Directives

Let’s suppose we have a directive called MyDirective like this:

@Directive({
  selector:'[my-directive]',
  exportAs:'mydirective' 
})
class MyDirective{
  sayHello(param){
    console.log('Hello from directive, ', param);
  }
}

We can use it in our component template as follows:

<div my-directive>Angular 10!</div>

We can access the directive using ViewChild using the following code:

// [...]
export class AppComponent{
  @ViewChild(MyDirective) myDirective;

  ngAfterViewInit(){
    this.myDirective.sayHello('This is a parameter!');
  }
}

Conclusion

In this tutorial we have seen by example how to use ViewChild, ElementRef and ngAfterViewInit to access native DOM elements, child components and directives used in the parent component’s template.

Leave a Reply

Skip to toolbar