ANGULAR
Complete Angular Tutorial For Beginners Introduction to Angular | What is Angular? Architecture Overview & Concepts of Angular How to Install Angular How to Create a new project in Angular Bootstrapping in Angular: How It Works Internally Angular Components Overview & Examples Data Binding in Angular Interpolation in Angular Property Binding in Angular Event Binding in Angular ngModel & Two way Data binding in Angular NgModelChange & Change Event in Angular Child/Nested Components in Angular angular directives angular ngFor directive ngSwitch, ngSwitchcase, ngSwitchDefa ult Angular Example How to use ngIf, else, then in Angular By example NgClass Example Conditionally apply class Angular ngStyle Directive Angular Trackby to improve ngFor Performance How to Create & Use Custom Directive In Angular Working with Angular Pipes How to Create Custom Pipe in Angular Formatting Dates with Angular Date Pipe Using Angular Async Pipe with ngIf & ngFor angular keyValue pipe Using Angular Pipes in Components or Services Angular Component Communication & Sharing Data Angular Pass data to child component Angular Pass data from Child to parent component Component Life Cycle Hooks in Angular Angular ngOnInit And ngOnDestroy Life Cycle hook Angular ngOnChanges life Cycle Hook Angular ngDoCheck Life Cycle Hook Angular Forms Tutorial: Fundamentals & Concep t s Angular Template-driven forms example How to set value in template-driven forms in Angular Angular Reactive Forms Example Using Angular FormBuilder to build Forms SetValue & PatchValue in Angular StatusChanges in Angular Forms ValueChanges in Angular Forms FormControl in Angular FormGroup in Angular Angular FormArray Example Nested FormArray Example Add Form Fields Dynamically SetValue & PatchValue in FormArray Angular Select Options Example in Angular Introduction to Angular Services Introduction to Angular Dependency Injection Angular Injector, @Injectable & @Inject Angular Providers: useClass, useValue, useFactory & useExisting Injection Token in Angular How Dependency Injection & Resolution Works in Angular Angular Singleton Service ProvidedIn root, any & platform in Angular @Self, @SkipSelf & @Optional Decorators Angular '@Host Decorator in Angular ViewProviders in Angular Angular Reactive Forms Validation Custom Validator in Angular Reactive Form Custom Validator with Parameters in Angular Inject Service Into Validator in Angular template_driven_form_validation_in_angular Custom Validator in Template Driven Forms in Angular Angular Async Validator Example Cross Field or Multi Field Validation Angular How to add Validators Dynamically using SetValidators in Angular Angular HttpClient Tutorial & Example Angular HTTP GET Example using httpclient Angular HTTP POST Example URL Parameters, Query Parameters, httpparams in Angular HttpClient Angular HTTPHeaders Example Understanding HTTP Interceptors in Angular Angular Routing Tutorial with Example Location Strategy in Angular Angular Route Params Angular : Child Routes / Nested Route Query Parameters in Angular Angular Pass Data to Route: Dynamic/Static RouterLink, Navigate & NavigateByUrl to Navigate Routes RouterLinkActive in Angular Angular Router Events ActivatedRoute in Angular Angular Guards Tutorial Angular CanActivate Guard Example Angular CanActivateChild Example Angular CanDeactivate Guard Angular Resolve Guard Introduction to Angular Modules or ngModule Angular Routing between modules Angular Folder Structure Best Practices Guide to Lazy loading in Angular Angular Preloading Strategy Angular CanLoad Guard Example Ng-Content & Content Projection in Angular Angular @input, @output & EventEmitter Template Reference Variable in Angular ng-container in Angular How to use ng-template & TemplateRef in Angular How to Use ngTemplateOutlet in Angular '@Hostbinding and @Hostlistener_in_Angular Understanding ViewChild, ViewChildren &erylist in Angular ElementRef in Angular Renderer2 Example: Manipulating DOM in Angular ContentChild and ContentChildren in Angular AfterViewInit, AfterViewChecked, AfterContentInit & AfterContentChecked in Angular Angular Decorators Observable in Angular using RxJs Create observable from a string, array & object in angular Create Observable from Event using FromEvent in Angular Using Angular observable pipe with example Angular Map Operator: Usage and Examples Filter Operator in Angular Observable Tap operator in Angular observable Using SwitchMap in Angular Using MergeMap in Angular Using concatMap in Angular Using ExhaustMap in Angular Take, TakeUntil, TakeWhile & TakeLast in Angular Observable First, Last & Single Operator in Angular Observable Skip, SkipUntil, SkipWhile & SkipLast Operators in Angular The Scan & Reduce operators in Angular DebounceTime & Debounce in Angular Delay & DelayWhen in Angular Using ThrowError in Angular Observable Using Catcherror Operator in Angular Observable ReTryWhen inReTry, ReTryWhen in Angular Observable Unsubscribing from an Observable in Angular Subjects in Angular ReplaySubject, BehaviorSubject & AsyncSubject in Angular Angular Observable Subject Example Sharing Data Between Components Angular Global CSS styles View Encapsulation in Angular Style binding in Angular Class Binding in Angular Angular Component Styles How to Install & Use Angular FontAwesome How to Add Bootstrap to Angular Angular Location Service: go/back/forward Angular How to use APP_INITIALIZER Angular Runtime Configuration Angular Environment Variables Error Handling in Angular Applications Angular HTTP Error Handling Angular CLI tutorial ng new in Angular CLI How to update Angular to latest version Migrate to Standalone Components in Angular Create Multiple Angular Apps in One Project Set Page Title Using Title Service Angular Example Dynamic Page Title based on Route in Angular Meta service in Angular. Add/Update Meta Tags Example Dynamic Meta Tags in Angular Angular Canonical URL Lazy Load Images in Angular Server Side Rendering Using Angular Universal The requested URL was not found on this server error in Angular Angular Examples & Sample Projects Best Resources to Learn Angular Best Angular Books in 2020

Understanding ViewChild, ViewChildren & Querylist in Angular

The ViewChild or ViewChildren decorators are used to Query and get the reference of the DOM element in the Component. ViewChild returns the first matching element and ViewChildren returns all the matching elements as a QueryList of items. We can use these references to manipulate element properties in the component.

To Query a DOM element(s), we must supply the query selector, which can be a string or a type as the first argument to the ViewChild or ViewChildren. The argument static determines whether the query is performed, before or after the change detection. The read option allows us to query a different token rather than the default and is useful when the element is associated with multiple types. We will learn all these in this tutorial.

ViewChild

The ViewChild query returns the first matching element from the DOM and updates the component variable on which we apply it.

Syntax

The Syntax of the viewChild is as shown below.

                              
 
ViewChild(selector: string | Function | Type<any>, opts: { read?: any; static: boolean; }): any
 

                            
                        

We apply the viewChild decorator on a Component Property. It takes two arguments. A selector and opts.

selector: can be a string, a type or a function that returns a string or type. The change detector looks for the first element that matches the selector and updates the component property with the reference to the element. If the DOM changes and a new element matches the selector, the change detector updates the component property.

opts: has two options.

static Determines when the query is resolved. True is when the view is initialized (before the first change detection) for the first time. False if you want it to be resolved after every change detection

read: Use it to read the different token from the queried elements.

ViewChild Examples

Now, let us learn ViewChild using few examples.

Injecting Component or Directive Reference

One of the use cases of ViewChild is to get the reference of the Child Component in the Parent Component and manipulate its properties. This is one of the ways by which the Parent can communicate with the child components.

For Example consider the following ChildComponent. It has two methods. Increment & Decrement.

                              
 
import { Component } from '@angular/core';
 
@Component({
  selector: 'child-component',
  template: `<h2>Child Component</h2>
            current count is {{ count }}
    `
})
export class ChildComponent {
  count = 0;
 
  increment() {
    this.count++;
  }
  decrement() {
    this.count--;
  }
}
 
                            
                        

We can use the ViewChild in the parent component to get the reference to the ChildComponent

                              

@ViewChild(ChildComponent, {static:true}) child: ChildComponent;
                            
                        

In the code above, the ViewChild looks for the first occurrence of the ChildComponent in the view and updates the child variable. Now we can invoke the methods Increment & Decrement of the ChildComponent from the Parent.

The complete code is as shown below.

                              

import { Component, ViewChild } from '@angular/core';
import { ChildComponent } from './child.component';
 
@Component({
  selector: 'app-root',
  template: `
        <h1>{{title}}</h1>
        <p> current count is {{child.count}} </p>
        <button (click)="increment()">Increment</button>
        <button (click)="decrement()">decrement</button>
        <child-component></child-component>
        ` ,
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Parent calls an @ViewChild()';
  
  @ViewChild(ChildComponent, {static:true}) child: ChildComponent;
 
  increment() {
    this.child.increment();
  }
 
  decrement() {
    this.child.decrement();
  }
 
}
 
                            
                        

Using Template Reference Variable

You can make use of Template Reference Variable instead of the component type.

For Example, you can assign a Template Reference Variable to a component.

                              
 
<child-component #child></child-component>
                            
                        

and then use it in the ViewChild query to get the reference to the component.

                              

 @ViewChild("child", { static: true }) child: ChildComponent;
                            
                        

Injecting HTML Element Using ElementRef

The Viewchild can also be used to query HTML elements.

First, assign a Template variable (#para in the example below) to the HTML element. You can then use the ViewChild to query the element.

ViewChild returns a ElementRef, which is nothing but a wrapper around the native HTML element.

                              

import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';
 
@Component({
    selector: 'htmlelement',
    template: `
      <p #para>Some text</p>
    `,
})
export class HTMLElementComponent implements AfterViewInit {
 
    @ViewChild('para',{static:false}) para: ElementRef;
 
    ngAfterViewInit() {
      console.log(this.para.nativeElement.innerHTML);
      this.para.nativeElement.innerHTML="new text"
    }
}
 
                            
                        

Multiple Instances

There could be multiple instances of the same component or element in the Template.

                              
 
<child-component></child-component>
<child-component></child-component>
 
                            
                        

The ViewChild always returns the first component.

                              

@ViewChild(ChildComponent, {static:true}) child: ChildComponent;
                            
                        

To get all the instances of the Child Component, we can make use of the ViewChildren, which we cover later in this tutorial.

ViewChild returns Undefined

ViewChild Returning undefined is one of the common errors, we encounter when we use them.

The error is due to the fact that we try to use the value, before the ViewChild initializes it.

For Example, the code below results in Cannot read property 'increment' of undefined. i.e. the component’s view is not yet initialized when the constructor is run. Hence, the Angular yet to update child variable with the reference to the ChildComponet.

                              

export class AppComponent {
  title = 'Parent calls an @ViewChild()';
  
  @ViewChild(ChildComponent, {static:true}) child: ChildComponent;
 
  constructor() {
    this.child.increment()
  } 
 
}
 
//
Cannot read property 'increment' of undefined
                            
                        

The solution is to wait until the Angular Initializes the View. Angular raises the AfterViewInit life cycle hook once it completes the View Initialization. So we can use the ngAfterViewInit to access the child variable.

                              
 
  ngAfterViewInit() {
    this.child.increment()
  }
 
                            
                        

Now, the code does not give any errors.

Also, when ViewChild updates the values also depends on the static option

Using Static Option in ViewChild

We used the {static:true} in the above code.

The static option determines the timing of the ViewChild query resolution.

  • static:true will resolves ViewChild before any change detection is run.
  • static:false will resolves it after every change detection run.
  • The value of the static becomes important when the child is rendered dynamically. For Example inside a ngIf or ngSwitch etc.

    For Example consider the following code, where we have moved the child-component inside the ngIf.

    child.component.html code box -->
                                  
    
    
     
    <h1>ViewChild Example</h1>
     
    <input type="checkbox" id="showCounter" name="showCounter" [(ngModel)]="showCounter">
     
    <ng-container  *ngIf="showCounter">
     
      <p> current count is {{child?.count}} </p>
     
      <button (click)="increment()">Increment</button>
      <button (click)="decrement()">decrement</button>
     
      <child-component></child-component>
     
    </ng-container>
                                
                            
                                  
     
    
     
    import { Component, ViewChild, AfterViewInit, OnInit, ChangeDetectorRef } from '@angular/core';
    import { ChildComponent } from './child.component';
     
    @Component({
      selector: 'app-root',
      templateUrl: 'app.component.html' ,
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      title = 'ViewChild Example)';
     
      showCounter: boolean = true
     
      @ViewChild(ChildComponent, { static: true }) child: ChildComponent;
     
      increment() {
        this.child.increment();
      }
     
      decrement() {
        this.child.decrement();
      }
     
    }
     
                                
                            

    The above code results in a TypeError: Cannot read property 'increment' of undefined. The error occurs even if we assign true to showCounter

    Because in the above case Angular does not render the child component immediately. But after the first change detection which detects the value of showCounter and renders the child component.

    Since we used static: true, the angular will try to resolve the ViewChild before the first change detection is run. Hence the child variable always will be undefined.

    Since we used static: true, the angular will try to resolve the ViewChild before the first change detection is run. Hence the child variable always will be undefined.

    Now, change the static: false. Now the code will work correctly. I.e because after every change detection the Angular updates the ViewChild

    Using the Read Option in ViewChild

    A Single element can be associated with multiple types.

    For Example, consider the following code. #nameInput template variable is now associated with both input & ngModel

                                  
    
    <input #nameInput [(ngModel)]="name">
                                
                            

    The viewChild code below, returns the instance of the input element as elementRef.

                                  
     
     @ViewChild('nameInput',{static:false}) nameVar;
                                
                            

    If we want to get the instance of the ngModel, then we use the Read token and ask for the type.

                                  
     
    @ViewChild('nameInput',{static:false, read: NgModel}) inRef;
     
    @ViewChild('nameInput',{static:false, read: ElementRef}) elRef;
    @ViewChild('nameInput', {static:false, read: ViewContainerRef }) vcRef;
     
                                
                            

    Every element in Angular is always has a ElementRef and ViewContainerRef associated with it. If the element is a component or directive then there is always a component or directive instance. You can also apply more than one directive to an element.

    The ViewChild without read token always returns the component instance if it is a component. If not it returns the elementRef.

    Injecting a Provider from the Child Component

    You can also inject the services provided in the child component.

                                  
    
    import { ViewChild, Component } from '@angular/core';
     
    @Component({
      selector: 'app-child',
      template: `<h1>Child With Provider</h1>`,
      providers: [{ provide: 'Token', useValue: 'Value' }]
    })
     
    export class ChildComponent{
    }
     
                                
                            

    And in the Parent component, you can access the provider using the read property.

                                  
     
    import { ViewChild, Component } from '@angular/core';
     
    @Component({
      selector: 'app-root',
      template: `<app-child></app-child>`,
    })
     
    export class AppComponent{
        @ViewChild(ChildComponent , { read:'Token', static:false } ) childToken: string;
    }
     
                                
                            

    Injecting TemplateRef

    You can access the TemplateRef as shown below

                                  
    
     
    <ng-template #sayHelloTemplate>
      <p> Say Hello</p>
    </ng-template>
     
                                
                            

    Component code

                                  
    
    @ViewChild("sayHelloTemplate", { static: false }) tempRef: TemplateRef;
                                
                            

    ViewChildren

    ViewChildren decorator is used to getting the list of element references from the View.

    ViewChildren is different from the ViewChild. ViewChild always returns the reference to a single element. If there are multiple elements the ViewChild returns the first matching element,

    ViewChildren always returns all the elements as a QueryList. You can iterate through the list and access each element.

    Syntax

    The Syntax of the viewChildren is as shown below. It is very much similar to syntax of viewChild except for the static option.

                                  
    
    ViewChildren(selector: string | Function | Type<any>, opts: { read?: any; }): any
                                
                            

    QueryList

    The QueryList is the return type of ViewChildren and contentChildren .

    QueryList stores the items returned by the viewChildren or contentChildren in a list.

    The Angular updates this list, whenever the state of the application change. It does it on each change detection.

    Changes can be observed by subscribing to the changes Observable.

    You can use the following methods & properties.

  • first: returns the first item in the list.
  • last: get the last item in the list.
  • length: get the length of the items.
  • changes: Is an observable. It emits a new value, whenever the Angular adds, removes or moves the child elements.
  • It also supports JavaScript array methods like map(),filter() ,find(), reduce(),forEach(),some(). etc

    ViewChildren Example

    In the example below, we have three input elements all using the ngModel directive

    We use the ViewChildren to get the QueryList of all input elements

    Finally, we can use the this.modelRefList.forEach to loop through the QueryList and access each element.

                                  
    
    import { ViewChild, Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';
    import { NgModel } from '@angular/forms';
     
    @Component({
      selector: 'app-viewchildren1',
      template: `
          <h1>ViewChildren Example</h1>
     
          <input name="firstName" [(ngModel)]="firstName">
          <input name="midlleName" [(ngModel)]="middleName">
          <input name="lastName" [(ngModel)]="lastName">
     
          <button (click)="show()">Show</button>
      
      `,
    })
     
    export class ViewChildrenExample1Component {
     
      firstName;
      middleName;
      lastName;
     
      @ViewChildren(NgModel) modelRefList: QueryList<NgModel>;
      
      show() {
     
        this.modelRefList.forEach(element => {
          console.log(element)
          //console.log(element.value)
        });
      }
    }
     
                                
                            

    Listening for QueryList Changes

    We can subscribe to the changes observable to find if any new elements are added/removed or moved.

    In the example below, we have included ngIf directive to hide/show the input elements.

    We subscribe to the changes observable in the component class. Every time we use the ngIf to hide or add the component, the changes observable emits the latest QueryList.

    We subscribe to the changes observable in the component class. Every time we use the ngIf to hide or add the component, the changes observable emits the latest QueryList.

                                  
    
    import { ViewChild, Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core';
    import { NgModel } from '@angular/forms';
     
    @Component({
      selector: 'app-viewchildren2',
      template: `
          <h1>ViewChildren Example</h1>
     
          <input *ngIf="showFirstName" name="firstName" [(ngModel)]="firstName">
          <input *ngIf="showMiddleName" name="midlleName" [(ngModel)]="middleName">
          <input *ngIf="showlastName" name="lastName" [(ngModel)]="lastName">
     
     
          <input type="checkbox" id="showFirstName" name="showFirstName" [(ngModel)]="showFirstName">
          <input type="checkbox" id="showMiddleName" name="showMiddleName" [(ngModel)]="showMiddleName">
          <input type="checkbox" id="showlastName" name="showlastName" [(ngModel)]="showlastName">
     
          <button (click)="show()">Show</button>
      
      `,
     
    })
     
    export class ViewChildrenExample2Component implements AfterViewInit {
     
      firstName;
      middleName;
      lastName;
     
      showFirstName=true;
      showMiddleName=true;
      showlastName=true;
     
      @ViewChildren(NgModel) modelRefList: QueryList<NgModel>;
     
      ngAfterViewInit() {
     
        this,this.modelRefList.changes
          .subscribe(data => {
            console.log(data)
          }
        )
      }
      
     
      show() {
        this.modelRefList.forEach(element => {
          console.log(element)
          //console.log(element.value)
        });
     
      }
    }