How to use ViewChild and ViewChildren in Angular

How to use ViewChild and ViewChildren in Angular

This article is focused on understanding the usage of @ViewChild and @ViewChildren inside Angular components. We will look at how to effectively use these functionalities to achieve your desired results.

A component can obtain a reference to an element or directive so we can access it directly. The directive can be either Angular’s own or a user-defined custom directive. We can sometimes require access to the element or component directly and manipulate the properties of the component or element. This is somehow the same as getting a DOM element using JavaScript and updating the property and behavior of the DOM element.

Working With Angular’s ViewChild

@ViewChild can be used to get the reference of the DOM element rendered inside an Angular component. We can use the reference of the DOM element to manipulate element properties. To get the component, we need to specify the selector.

// Accessing DOM element with JavaScript
let domReference = document.getElementById("someElement");

// Access DOM element using Angular @ViewChild @ViewChild("someElement") domReference;

Access this code here

Given above is the code to access the DOM element using either plain JavaScript or Angular’s @ViewChild. Using JavaScript, we can use a selector to extract the component. Given our statement below, we are trying to access the element using an element ID.

<div id=”someElement”>Sample Code</div>

Given below is a div element having a template reference marked as someElement. Template references start with #. In the case of Angular, we can access the elements using these template references. The element reference can be retrieved by using @ViewChild and the template-reference variable specified for the same. Let’s look at this in action.

<div #someElement>Sample Code</div>

When Can We Refer to This ViewChild Variable?

The reference to a @ViewChild variable is assigned once the View has been initialized. Angular provides a life-cycle Hook called ngAfterViewInit, which is called once the View has been initialized. Once the View is initialized and rendered, the @ViewChild can then access the element using the template reference. It provides us with access to the element/directive.

Let’s look at the code:

@Component({
  selector: 'accessing-template-reference',
  template: '<div><input type="text" #someElement />'
})
export class HeroListComponent implements OnInit {
  @ViewChild("someElement") domReference;

ngAfterViewInit(): void { this.domReference.nativeElement.focus(); } }

Access this code here

In the code above, the following points need to be considered:

1.    We can access the input element having the template-reference variable “someElement” using @ViewChild.

2.  The ViewChild element domReference will receive access to the DOM element only after it has been rendered. Once the component is rendered, a life-cycle event called ngAfterViewInit is invoked. So we can refer to the element in this life-cycle event or in later life-cycle events.

3.  @ViewChild can enable the user to access the native DOM element of the View rendered. Using this DOM reference, we can access and modify DOM properties like manipulating style, innerText, value, and other properties related to an element referred.

4.  We are directly accessing the DOM, so we are tightly coupled with the browser. So we may not be able to use these references using server-side rendering, and it also may pose security threats.

Accessing Element Using Angular Directive

We can use Angular directives like NgModel with @ViewChild. Let’s look for the requirement and use case scenarios for accessing Angular directives using @ViewChild.

@Component({
  selector: 'accessing-template-reference',
  template:     &lt;div&gt;       &lt;input type="text" id="userName" [(ngModel)]="userName" /&gt;     &lt;/div&gt;  
})
export class HeroListComponent implements OnInit {
  @ViewChild(NgModel) userNameReference: NgModel;

ngAfterViewInit(): void { this.userNameReference,valueChanges.subscribe( () => { this.executeOtherFunction() } ) } }

Access this code here

We can access the NgModel directive inside @ViewChild and subscribe to value changes. Given above is the code, where we are trying to access an element using the Angular Directive NgModel. Element with the ID userName is having the directive NgModel added to it. Using @ViewChild, we will track changes to any value update inside the input element.

We get the reference to the input element’s NgModel data structure, and using reference, we can access its state information, like whether it has been modified or if the value is valid or not.

It can be accessed inside the ngAfterViewInit life cycle. We get access to all the state information. It also provides information about any updates to the property. This reference is read-only. It gives us access to observable, and we can use this observable to subscribe to the valueChanges observable.

Whenever the value is updated, a callback function associated with it is triggered, and we can add custom logic in response to the update.

Working With Angular’s ViewChildren

Working with @ViewChildren is similar to @ViewChild, but the difference between the two is @ViewChildren provides a list of element references rather than returning a single reference. It is used to reference multiple elements. We can then iterate the list of the element referenced by the variable.

The following selectors can be used with @ViewChildren:

1. We can use ViewChildren with Angular directives like NgModel

We can use inbuilt directives like NgModel with ViewChild. It will give the list of all the elements having the directive NgModel attached to it.

@Component({
  selector: 'accessing-template-reference',
  template:     &lt;div&gt;       &lt;input type="text" [(ngModel)]="userName" /&gt;       &lt;input type="text" [(ngModel)]="userAge" /&gt;       &lt;input type="text" [(ngModel)]="userDesignation" /&gt;     &lt;/div&gt;  
})
export class HeroListComponent implements OnInit {
  @ViewChildren("NgModel") domReference: QueryList<NgModel>;

ngAfterViewInit(): void { console.log("Element List: " + this.domReference.length); } }

View this code here

Given above is the code, which extracts the element using the Angular directive NgModel. All the components containing the specified Angular directive can be retrieved and further evaluated.

2. Accessing elements using child components

Similar to the usage of directives with @ViewChildren, we can use the child component name to access the elements using @ViewChildren. This just necessitates that we have some child component (e.g., user-details) inside our main component. Let’s see the following scenario with an example.

@Component({
  selector: 'accessing-template-reference',
  template:     &lt;div&gt;       &lt;user-details [userId]="firstUser"&gt;&lt;/user-details&gt;       &lt;user-details [userId]="secondUser"&gt;&lt;/user-details&gt;       &lt;user-details [userId]="thirdUser"&gt;&lt;/user-details&gt;     &lt;/div&gt;  
})
export class HeroListComponent implements OnInit {
  @ViewChildren("UserDetailComponent") userDetailReferences: QueryList<NgModel>;

ngAfterViewInit(): void { console.log("Element List: " + this.userDetailReferences.length); } }

View this code here

The code above gets the list of all the child-component references contained inside a parent component.

We can then use these references to accomplish custom logic. The developer can then use this list to accomplish further tasks.

3. Using template-reference variables

Multiple components inside the element can contain the same template reference. If we use a template reference in multiple places, we receive the reference list of all components referred by the same template-reference variable in the template.

@Component({
  selector: 'accessing-template-reference',
  template:     &lt;div&gt;       &lt;input type="text" #applicationInfo /&gt;       &lt;input type="text" #applicationInfo /&gt;       &lt;input type="text" #applicationInfo /&gt;     &lt;/div&gt;  
})
export class HeroListComponent implements OnInit {
  @ViewChildren("applicationInfo") applicationInfo: QueryList<NgModel>;

ngAfterViewInit(): void { console.log("Element List: " + this.applicationInfo.length); } }

View this code here

The code above contains multiple components with the same template-reference variable. @ViewChildren will enable the user to access all the components that refer to the template reference applicationInfo.

4. Accessing multiple template-reference variables

The selector can be a set of template references. We can specify multiple template references. All the components containing the template reference specified in the list are retrieved from the component.

@Component({
  selector: 'accessing-template-reference',
  template:     &lt;div&gt;       &lt;input type="text" #userName /&gt;       &lt;input type="text" #userAge /&gt;       &lt;input type="text" #userDesignation /&gt;     &lt;/div&gt;  
})
export class HeroListComponent implements OnInit {
  @ViewChildren("userName, userAge, userDesignation") userInfoReference: QueryList<NgModel>;

ngAfterViewInit(): void { console.log("Element List: " + this.userInfoReference.length); } }

View this code here

In the code above, we are adding the list of template-reference variables inside @ViewChildren. All the components containing the element reference contained in the list are retrieved and can be accessed with the variable name.

Working with ViewChild and Child Components

ViewChild and ViewChildren can be used to access the properties and methods of the child component. Using ViewChild and ViewChildren, we can get the reference of the child component, which further gives access to all the properties and methods. This can enable a parent component to access the child component and enable communication between them.

Let’s look at the code to understand the concept better:

@Component({
  selector: 'child-component',
  template:     &lt;div&gt;       &lt;input type="text" [(ngModel)]="userName" /&gt;     &lt;/div&gt;  
})
export class ChildComponent implements OnInit {

public userName: string;

updateUserName(): void { this.userName = "Mayank" } }

View this code here

The code above contains a simple child component, which has the property userName and the function updateUserName, prescribed to update the userName property of the component.

Now let’s add a new component that will act as a parent component for the above ChildComponent. We will look into the code to access the child component’s properties and methods from the parent component using @ViewChild. Let’s look at the code below.

@Component({
  selector: 'child-component',
  template:     &lt;div&gt;       &lt;b&gt;This is the Parent Component Accessing Child Component&lt;/b&gt;       &lt;child-component #userInformation&gt;&lt;/child-component&gt;       &lt;input type="button" value="Update User Name" (click)="updateUserData()" /&gt;     &lt;/div&gt;  
})
export class ParentComponent implements OnInit {
  @ViewChild("userInformation") childComponentReference: any;

updateUserData() {

// Accessing Property of Child Component
this.childComponentReference.userName = "Updated Name";

// Accessing Functions of Child Component
this.childComponentReference.updateUserName();

} }

View this code here

The above code represents a parent component. In the template specified for the parent component, we have a child component added.

The child component is marked with a template-reference variable. We can use this template reference to access the properties and variables of the child component.

@ViewChild(“userInformation”) childComponentReference: any;

@ViewChild can be used to access the child component having the template reference userInformation, which represents the child component. Using this childComponentReference, we can further access the properties and call the function of the child component, as specified above.

Conclusion

I hope the article was informative for you. Feel free to leave a comment below.

Originally published by Mayank Gupta at medium.com

============================================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

Angular 8 Pagination Example and Tutorial

Angular 8 + Spring Boot 2.2: Build a CRUD App Today!

Angular 8 Forms Tutorial - Reactive Forms Validation Example

Angular 8 Tutorial By Example: (REST API, HttpClient GET, Components, Services & ngFor)

angular web-development

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire Web Developer

Looking for an attractive & user-friendly web developer? HourlyDeveloper.io, a leading web, and mobile app development company, offers web developers for hire through flexible engagement models. You can **[Hire Web...

Why Web Development is Important for your Business

With the rapid development in technology, the old ways to do business have changed completely. A lot more advanced and developed ways are ...

Important Reasons to Hire a Professional Web Development Company

    You name the business and I will tell you how web development can help you promote your business. If it is a startup or you seeking some...

Wondering how to upgrade your skills in the pandemic? Here's a simple way you can do it.

Corona Virus Pandemic has brought the world to a standstill. Countries are on a major lockdown. Schools, colleges, theatres, gym, clubs, and all other public

Hire Dedicated eCommerce Web Developers | Top eCommerce Web Designers

Build your eCommerce project by hiring our expert eCommerce Website developers. Our Dedicated Web Designers develop powerful & robust website in a short span of time.