prabhat gundepalli
prabhat gundepalli

Reputation: 967

Angular: Calling SelectedTabChange only for rendered tabs

I have a group of tabs in Angular material tab group as below and calling a method setGridHeight in every component ( every tab ).

<mat-tab-group [dynamicHeight]="true" (selectedTabChange)='queue0.setGridHeight();queue1.setGridHeight();queue2.setGridHeight();'>
  <mat-tab *ngIf='showQueues[0]'>
    <ng-template mat-tab-label>
      <i class="fa fa-share-square" routerLink="/queue/0" style="color: rgb(8, 148, 148)"></i>Queue 0
    </ng-template>
    <fph-queue-0 #queue0 [rowData]="queue0Items$ | async">
    </fph-queue-0>
  </mat-tab>
  <mat-tab *ngIf='showQueues[1]'>
    <ng-template mat-tab-label>
      <i class="fa fa-share-square" routerLink="/queue/1" style="color: rgb(8, 148, 148)"></i>Queue 0
    </ng-template>
    <fph-queue-1 #queue1 [rowData]="queue1Items$ | async">
    </fph-queue-1>
  </mat-tab>
  <mat-tab *ngIf='showQueues[2]'>
    <ng-template mat-tab-label>
      <i class="fa fa-share-square" routerLink="/queue/2" style="color: rgb(8, 148, 148)"></i>Queue 0
    </ng-template>
    <fph-queue-2 #queue2 [rowData]="queue2Items$ | async">
    </fph-queue-2>
  </mat-tab>
</mat-tab-group>

So in the TS code in every component I am calling a method called setGridHeight which is called on tab change.

The issue is if I control the components redering through *ngIf, the selectedtabChange call throws an error ( since it cant call a method of an unrendered component( unrendered tab) )

How do I then change the call to only methods from only rendered components ( tabs ).

for ex: showQueues = [true, false, true];

showQueues[1] = false and is not rendered and thus queue1.setGridHeight() throws an exception Cannot read property 'setGridHeight' of undefined.

Upvotes: 0

Views: 4594

Answers (3)

Pankaj Parkar
Pankaj Parkar

Reputation: 136184

You should ideally set single template variable name to all tab content like #queue and there after query all the rendered component by using ViewChildren like below

@ViewChildren('queue', {read: ViewContainerRef}) queue;

ViewContainerRef is must to grab reference of that component.

It will return rendered tab that has #queue template variable, now you can easily loop over each tab on selectedTabChange event.

onTabChanged () {
    this.queue.forEach(q => q.setGridHeight());
} 

Demo Here

Upvotes: 1

Learning
Learning

Reputation: 1413

Check if the ‘queue1’ is not undefined and not null:

If (undefined !== queue1 && queue1 != null) {
  queue1.setGridHeight();
}

Upvotes: 0

Sunil
Sunil

Reputation: 11241

One of the quickest solution would be to change *ngIf to [hidden]

<mat-tab-group [dynamicHeight]="true" (selectedTabChange)='queue0.setGridHeight();queue1.setGridHeight();queue2.setGridHeight();'>
  <mat-tab [hidden]='!showQueues[0]'>
    <ng-template mat-tab-label>
      <i class="fa fa-share-square" routerLink="/queue/0" style="color: rgb(8, 148, 148)"></i>Queue 0
    </ng-template>
    <fph-queue-0 #queue0 [rowData]="queue0Items$ | async">
    </fph-queue-0>
  </mat-tab>
  <mat-tab [hidden]='!showQueues[1]'>
    <ng-template mat-tab-label>
      <i class="fa fa-share-square" routerLink="/queue/1" style="color: rgb(8, 148, 148)"></i>Queue 0
    </ng-template>
    <fph-queue-1 #queue1 [rowData]="queue1Items$ | async">
    </fph-queue-1>
  </mat-tab>
  <mat-tab [hidden]='!showQueues[2]'>
    <ng-template mat-tab-label>
      <i class="fa fa-share-square" routerLink="/queue/2" style="color: rgb(8, 148, 148)"></i>Queue 0
    </ng-template>
    <fph-queue-2 #queue2 [rowData]="queue2Items$ | async">
    </fph-queue-2>
  </mat-tab>
</mat-tab-group>

Upvotes: 0

Related Questions