Exploring ViewChild and ViewChildren in Angular
Angular offers a pair of powerful property decorators known as ViewChild and ViewChildren. These tools are essential for interacting with elements and child components within a component's template.
At their core, both decorators serve a similar purpose: they provide a way to gain a reference to, and subsequently manipulate, elements defined in the same template or to access child component instances.
Syntax breakdown
@ViewChild(selector, {read: readValue, static: staticValue})
propertyName
We'll delve into the specifics of this syntax as we progress through the examples.
To illustrate these concepts, let's build a counter component. This component will hold a counter value, starting at 0, and expose two methods to increment or decrement it by a specified amount, x. Our goal is to invoke these methods from a parent component.
First, we need to set up our environment. Let's create a component named my-counter and declare it as a child of the app-component. If you need a refresher on setting up parent-child relationships, this post provides a helpful guide.
After creating the component, we'll begin by adding the necessary code to its TypeScript file.
counter = 0;
constructor() { }
ngOnInit(): void { }
increaseCounter(x: number) {
this.counter += x;
}
decreaseCounter(x: number) {
this.counter -= x;
}
Next, we'll update the corresponding template file.
<p>Counter Value: {{ counter }}</p>
Now, let's switch our attention to the app.component.ts file and add the following starter code.
increaseCounter(x: number) { }
decreaseCounter(x: number) { }
The methods' implementations will be filled in shortly. And for the associated template:
<input (click)="increaseCounter(1)" type="button"
value="Add by 1">
<input (click)="decreaseCounter(1)" type="button"
value="Subtract by 1">
Current output -
The button remains non-functional for now, but it will spring to life shortly.
Let's now get to the core of the matter.
First up: ViewChild.
We'll introduce a property called counterReference in app.component. This property is designed to hold a reference to the Counter component instance.
counterReference = {} as MyCounterComponent;
This property must be adorned with the ViewChild decorator. The final implementation looks like this:
@ViewChild(MyCounterComponent)
counterReference = {} as MyCounterComponent;
The ViewChild decorator accepts several parameters. The first, and most crucial, is the selector—in this case, the specific Component type you wish to obtain a reference to. Additionally, you can query using a template reference variable, a technique we'll explore shortly.
With the reference in hand, we can now implement the two previously empty methods.
increaseCounter(x: number) {
this.counterReference.increaseCounter(1);
}
decreaseCounter(x: number) {
this.counterReference.decreaseCounter(1);
}
As demonstrated, with the counterReference property properly decorated, we can directly call the methods of the MyCounterComponent instance.
Clicking either button will now alter the counter's value.
This illustrates the fundamental concept: a parent component can leverage ViewChild to interact with its child's public API.
Now, let's examine an alternative approach using a template reference variable. Here’s a simple example of such a reference:
<div #myTemplateRef></div>
<app-my-counter #componentTemplateRef></app-my-counter>
Notice the # symbol. This notation creates a variable that serves as a reference to an element or component within the template. In the snippet above, myTemplateRef and componentTemplateRef are the template reference variables.
To see this in action, let's update the component's TypeScript file with a few more lines.
@ViewChild('myTemplateRef')
myTemplateRef = {};
@ViewChild('componentTemplateRef')
componentTemplateRef = {};
And in the corresponding template file:
<div #myTemplateRef></div>
<app-my-counter #componentTemplateRef></app-my-counter>
Here's a critical piece of knowledge regarding the lifecycle of ViewChild.
When you generate a component using the CLI, you might have noticed the ngOnInit() method. This is one of Angular's lifecycle hook methods, and I'll cover all of them in detail in a future post. Crucially, there's another hook called ngAfterViewInit().
The ngAfterViewInit() method is invoked after the component's view (and its child views) have been fully initialized, meaning the view is ready. At this point, all properties decorated with ViewChild are available for use. Conversely, before this hook fires—for instance, within ngOnInit—these properties remain uninitialized or undefined.
To illustrate, here's what the properties look like inside ngOnInit:
And here's how they appear within ngAfterViewInit:
Here's a visual summary of the lifecycle:
The static option:
By default, the static flag is set to false.
Setting it to true enables support for creating embedded views at runtime. I'll revisit the static: true configuration when we discuss dynamic component creation in more depth.
Let's now shift our focus to ViewChildren. This decorator works much like ViewChild, but instead of a single reference, it returns all matching references as a QueryList.
A QueryList is an immutable collection that Angular maintains, automatically updating it whenever the application state changes and children are added, removed, or moved.
The QueryList offers several useful properties and methods:
- first: Returns the first item in the list.
- last: Returns the last item in the list.
- length: Returns the number of items in the list.
- changes: An observable that emits a new value whenever the list of children changes.
You can also use standard JavaScript array methods on a QueryList, such as map(), filter(), find(), and forEach().
Consider a scenario where you have three instances of the same component in your template.
<app-my-counter></app-my-counter>
<app-my-counter></app-my-counter>
<app-my-counter></app-my-counter>
When you need to access and interact with all these instances, ViewChildren is the ideal solution.
@ViewChildren(MyCounterComponent)
viewChildrenRef: QueryList<MyCounterComponent> | undefined;
By using ViewChildren, you can retrieve all instances matching your selector. This allows you to iterate over the collection and perform any necessary operations.
That concludes this exploration of these powerful Angular features.
I hope you found this information useful and engaging.
If you enjoyed this content, your support through likes ❤️, shares 💞, and comments 🧡 is always appreciated.
There are more Angular topics on the horizon, so stay tuned for future posts.
I'll be sharing more tips and tricks on Angular, JavaScript, TypeScript, and CSS over on Twitter.
I look forward to connecting with you there 😃
Cheers 🍻
Happy Coding

