angular tutorials

ViewChild in Angular 9 Example

This tutorial guides you on ViewChild in Angular 9 with example. You will also learn how to fetch local references through @ViewChild in Angular 9.

What is ViewChild in Angular 9 ?

ViewChild is an angular property that configures a view query. The change detector detects the view DOM changes and when a new child matches the selector (template reference variable), the property will be updated. The change detector looks for the template reference variable matching the selector in the view DOM.

To fetch local references i.e., template reference variables through ViewChild you can declare angular property of type ElementRef in your component class as shown below.

Syntax

@ViewChild('<local-reference-selector>', {static: true}) <viewchild-property-name>: ElementRef;

Example

 @ViewChild('itemDescInput', {static:true}) itemDescInput: ElementRef;

ElementRef is a wrapper around a native element inside of a View. This ElementRef has the useful property that we can use called nativeElement property. To access the input element value via local references that is fetched through ViewChild you can access in the following way.

this.itemDescInput.nativeElement.value

Note, the following are the other selectors supported other than template reference variable.

  • Any class with the @Component or @Directive decorator
  • Any provider defined in the child component tree of the current component (e.g. @ViewChild(ExampleService) exampleService: ExampleService)
  • Any provider defined through a string token (e.g. @ViewChild(‘exampleToken’) exampleTokenVal: any)
  • A TemplateRef (e.g. query <ng-template></ng-template> with @ViewChild(TemplateRef) template;)

Next, let’s see a complete example which demonstrates the usage of both using local references in templates and how to access to the template and DOM with @ViewChild.

ViewChild in Angular 9 Example

The following is code sneppet of component’s template where we use local references in the template file.

Note, in the first case (#itemNameInput) we are passing local references through methods. And in the second case (#itemDescInput) we are passing local references through ViewChild.

create-item.component.html

<div class="row">
    <div class="col-xs-12">
      <p>Create Items and Specifications!</p>
      <label>Item Name</label>     
      <input 
          type="text" 
          class="form-control" 
          #itemNameInput>
      <label>Item Description</label>     
      <input 
          type="text" 
          class="form-control" 
          #itemDescInput>
      <br>
      <button
        class="btn btn-primary"
        (click)="onAddItem(itemNameInput)">Add Item</button>
      <button
        class="btn btn-primary"
        (click)="onAddItemSpec(itemNameInput)">Add Item Specifications</button>
    </div>
  </div>

Then, check how we are trying to fetch the local reference “#itemDescInput” through ViewChild Angular property in our component class.

create-item.component.ts

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

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

  @Output() itemAdded = new EventEmitter<{itemTitle: string, itemDesc: string}>();
  @Output() itemSpecAdded = new EventEmitter<{itemTitle: string, itemSpec: string}>();

  @ViewChild('itemDescInput', {static:true}) itemDescInput: ElementRef; 

  newItemSpec = '';

  constructor() { }

  ngOnInit(): void {
  }

  onAddItem(itemNameInput : HTMLInputElement) {        
    this.itemAdded.emit({      
        itemTitle: itemNameInput.value,        
        itemDesc: this.itemDescInput.nativeElement.value
    });
  }

  onAddItemSpec(itemNameInput : HTMLInputElement) {
    this.itemSpecAdded.emit({      
      itemTitle: itemNameInput.value, 
      itemSpec: this.newItemSpec
    });
  }

}

Therefore, with this you will get direct access to DOM elements in our template through @ViewChild. This will work perfectly without Two-Way Databinding.

Local references (Template Reference Variables):

<label>Item Name</label>
<input 
     type="text" 
     class="form-control" 
     #itemNameInput>
<label>Item Description</label>
<input 
     type="text" 
     class="form-control" 
     #itemDescInput>

Instead Of (Two-Way Databinding):

<label>Item Name</label>
<input type="text" class="form-control" [(ngModel)]="newItemName">

<label>Item Description</label>
<input type="text" class="form-control" [(ngModel)]="newItemDesc">

That’s all. Finally, you had learnt what is ViewChild in Angular and how to fetch local references through ViewChild.

Also See:

References:

guest
0 Comments
Inline Feedbacks
View all comments