Template querying in Angular using @ViewChild and @ViewChildren decorators.

Gurinderpal Singh Narang
3 min readNov 3, 2023

--

When we want to get a reference of an element from a template in an Angular component class, in that case we can use ViewChild and ViewChildren decorator, similarly to the javascript getElementBy method(getElementById, getElementsByClassName, getElementsByName, etc).

document.getElementsById('id');
document.getElementsByClassName('className');
document.getElementsByName('h1');

ViewChild:

  • ViewChild is a decorator used to query the first element or directive that matches the selector from the template.
  • It is often used to access and manipulate a single element or directive within a component’s view.
  • When we use ViewChild, it returns the first matching element as an instance of the referenced component or directive.
@ViewChild(MyComponent) myComponent: MyComponent;

ViewChildren:

  • ViewChildren is a decorator used to query all elements or directives that match the selector from the template.
  • It returns a QueryList that contains all matching elements or directives.
  • ViewChildren is useful when we want to access and manipulate multiple elements or directives within the view.
@ViewChildren(MyDirective) myDirectives: QueryList<MyDirective>;

QueryList is a collection type in Angular that provides additional methods and observables for working with the query results. We can use these decorators along with lifecycle hooks ngAfterViewInit to ensure the view is fully initialized before attempting to access the elements.

Here’s an example of how we might use these decorators within an Angular component:

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

@Component({
selector: 'my-component',
template: `
<my-directive></my-directive>
<my-directive></my-directive>
`,
})
export class MyComponent implements AfterViewInit {
@ViewChild(MyDirective) myDirective: MyDirective;
@ViewChildren(MyDirective) myDirectives: QueryList<MyDirective>;

ngAfterViewInit() {
// Access and manipulate the element or directive using ViewChild
this.myDirective.doSomething();

// Access and manipulate all matching elements or directives using ViewChildren
this.myDirectives.forEach(directive => directive.doSomething());
}
}

The @ViewChild decorator in Angular allows to specify an optional read property that helps control what type of object is retrieved from the view. Let’s take the following example:

@ViewChild('myElement', {read: ElementRef}) myElement: ElementRef;

Here, we are explicitly specifying that we want to retrieve the element with the template reference #myElement as an ElementRef object. This can be useful when we want to ensure that the object obtained via @ViewChild is specifically an ElementRef.

The {read: ElementRef} part indicates that we are reading the element as an ElementRef type. If the element referenced by #myElement is not an ElementRef, Angular will try to convert it into an ElementRef.

By using {read: ElementRef}, we make it clear that we expect to work with the native DOM element directly, and Angular ensures that we receive it as an ElementRef for manipulation.

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

@Component({
selector: 'app-my-component',
template: '<div #myElement>Initial Content</div>',
})
export class MyComponent implements AfterViewInit {
@ViewChild('myElement', {read: ElementRef}) myElement: ElementRef;

ngAfterViewInit() {
const nativeElement = this.myElement.nativeElement;
nativeElement.textContent = 'New Content';
}
}

In this example, by specifying {read: ElementRef} in @ViewChild, you ensure that myElement is of type ElementRef, and we can directly manipulate the native DOM element in the ngAfterViewInit lifecycle hook.

In summary, the @ViewChild and ViewChildrendecorators are used to access and manipulate elements, components, or directives within a component's view.

--

--

No responses yet