By Alligator and Bradley Kouchi

This article will introduce you to Angular’s ViewChild decorator.
There may be situations where you want to access a directive, child component, or a DOM element from a parent component class. The ViewChild decorator returns the first element that matches a given directive, component, or template reference selector.
If you would like to follow along with this tutorial:
@angular/cli.@angular/cli to create a new project to test ViewChild functionality in.This tutorial was verified with @angular/core v13.0.2 and @angular/cli v13.0.3.
ViewChild with DirectivesViewChild makes it possible to access directives.
Let’s say you have a SharkDirective. This directive will look for elements with the attribute appShark and prepend the text in the element with the word "Shark".
Ideally, you will use @angular/cli to generate your directive:
- ng generate directive shark --skip-tests
This command will create a shark.directive.ts file. And adds the directive to app.module.ts:
import { SharkDirective } from './shark.directive';
...
@NgModule({
declarations: [
AppComponent,
SharkDirective
],
...
})
Then, use ElementRef and Renderer2 to rewrite the text. Replace the contents of shark.directive.ts with the following:
import {
Directive,
ElementRef,
Renderer2
} from '@angular/core';
@Directive(
{ selector: '[appShark]' }
)
export class SharkDirective {
creature = 'Dolphin';
constructor(elem: ElementRef, renderer: Renderer2) {
let shark = renderer.createText('Shark ');
renderer.appendChild(elem.nativeElement, shark);
}
}
Next, add an appShark attribute to a span containing text in the component template. Replace the contents of app.component.html with the following:
<span appShark>Fin!</span>
When viewing the application in a browser, it will render the word "Shark" before the contents of the element:
OutputShark Fin!
Now, you can also access the creature instance variable of SharkDirective and set an extraCreature instance variable with its value. Replace the contents of app.component.ts with the following:
import {
Component,
ViewChild,
AfterViewInit
} from '@angular/core';
import { SharkDirective } from './shark.directive';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
extraCreature!: string;
@ViewChild(SharkDirective)
set appShark(directive: SharkDirective) {
this.extraCreature = directive.creature;
};
ngAfterViewInit() {
console.log(this.extraCreature); // Dolphin
}
}
This code used a setter to set the extraCreature variable. Notice that it waits for the AfterViewInit lifecycle hook to access the variable, as this is when child components and directives become available.
When viewing the application in a browser, you will still see the "Shark Fin!" message. However, in the console log, it will display:
OutputDolphin
The parent component was able to access the value from the directive.
ViewChild with DOM ElementsViewChild makes it possible to access native DOM elements that have a template reference variable.
Let’s say you have an <input> in the template with the #someInput reference variable. Replace the contents of app.component.html with the following:
<input #someInput placeholder="Your favorite sea creature">
Now, you can access the <input> with ViewChild and set the value. Replace the contents of app.component.ts with the following:
import {
Component,
ViewChild,
AfterViewInit,
ElementRef
} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
@ViewChild('someInput') someInput!: ElementRef;
ngAfterViewInit() {
this.someInput.nativeElement.value = 'Whale!';
}
}
When ngAfterViewInit fires the value of the <input> will be set to:
OutputWhale!
The parent component was able to set the value of the child DOM Element.
ViewChild with Child ComponentsViewChild makes it possible to access a child component and call methods or access instance variables that are available to the child.
Let’s say you have a PupComponent.
Ideally, you will use @angular/cli to generate your component:
- ng generate component pup --flat --skip-tests
This command will create pup.component.ts, pup.component.css, and pup.component.html files. And adds the component to app.module.ts:
import { PupComponent } from './pup.component';
...
@NgModule({
declarations: [
AppComponent,
PupComponent
],
...
})
Then, add a whoAmI method to PupComponent which returns a message:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-pup',
templateUrl: './pup.component.html',
styleUrs: ['./pup/component.css']
})
export class PupComponent implements OnInit {
constructor() { }
whoAmI() {
return 'I am a pup component!';
}
ngOnInit(): void {
}
}
Next, reference the child component in the app template. Replace the contents of app.component.html with the following:
<app-pup>pup works!</app-pup>
Now, you can call the whoAmI method from within the parent component class with ViewChild. Replace the contents of app.component.ts with the following:
import {
Component,
ViewChild,
AfterViewInit
} from '@angular/core';
import { PupComponent } from './pup.component';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements AfterViewInit {
@ViewChild(PupComponent) pup!: PupComponent;
ngAfterViewInit() {
console.log(this.pup.whoAmI()); // I am a pup component!
}
}
When viewing the application in a browser, the console log will display:
OutputI am a pup component!
The parent component was able to call the child component’s whoAmI method.
In this tutorial, you used ViewChild to access a directive, child component, and a DOM element from a parent component class.
If the reference changes to a new element dynamically, ViewChild will automatically update its reference.
In cases where you want to access multiple children, you would use ViewChildren instead.
If you’d like to learn more about Angular, check out our Angular topic page for exercises and programming projects.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Alligator.io is a developer-focused resource that offers tutorials and insights on a wide range of modern front-end technologies, including Angular 2+, Vue.js, React, TypeScript, Ionic, and JavaScript.
Former Technical Editor at DigitalOcean. Expertise in areas including Vue.js, CSS, React, and more.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.