Angular: Triggering SelectedTabChange exclusively for tabs that have been rendered

Within an Angular material tab group, I have a collection of tabs where each one triggers the method setGridHeight in every individual component (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 1
    </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 2
    </ng-template>
    <fph-queue-2 #queue2 [rowData]="queue2Items$ | async">
    </fph-queue-2>
  </mat-tab>
</mat-tab-group>

In every component's TypeScript code, I am invoking a method named setGridHeight upon tab change.

The challenge arises when I control component rendering through *ngIf; the call to selectedtabChange results in an error since it attempts to invoke a method on an unrevealed component (unrendered tab).

How can I adjust the call to target only methods from currently rendered components (tabs)?

For example:

showQueues = [true, false, true];

showQueues[1] = false, causing it not to be rendered and consequently leading to an exception when queue1.setGridHeight() is invoked:

Cannot read property 'setGridHeight' of undefined
.

Answer №1

To streamline your code, consider assigning the same template variable name to all tab content elements, such as #queue. Then, you can retrieve all the rendered components using ViewChildren like demonstrated below:

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

Having a reference to the ViewContainerRef is crucial for accessing that component.

This approach will fetch the rendered tabs with the #queue template variable, allowing you to easily iterate through each tab during the selectedTabChange event.

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

Check out the Demo Here

Answer №2

Consider a quick fix by switching from *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>

Answer №3

Verify that the variable 'queue1' is both defined and not null:

If (typeof queue1 !== 'undefined' && queue1 !== null) {
  queue1.adjustListSize();
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The continuous rerendering of my component occurs when I use a path parameter

In my project, I am working on utilizing a path parameter as an ID to fetch data for a specific entity. To accomplish this, I have developed a custom data fetching hook that triggers whenever there is a change in the passed parameters. For obtaining the bo ...

Encountering an issue while trying to import the validator module in NextJS 13

I encountered a peculiar issue while trying to import a module. Nextjs presented the following error message: ./application/sign_in/sign_in_store.ts:2:0 Module not found: Can't resolve 'validator' 1 | import { createEvent, createStore } fr ...

What is the most effective way to compare two arrays of objects in JavaScript?

I'm working on a function that needs to return an array of elements based on certain filters. Here is the code for the function: filter_getCustomFilterItems(filterNameToSearch: string, appliedFilters: Array<any>) { let tempFilterArray = []; ...

Which TypeScript AsyncGenerator type returns a Promise?

I am currently in the process of assigning a return type to the function displayed below: async function *sleepyNumbers() { // trying to determine TypeScript type let n = 0; while (true) { yield new Promise(resolve => resolve(n++)); ...

Expandable rows within an Angular Material table (mat-table) feature a distinct gap, even when rows are collapsed

I recently integrated an Angular Material table into my website, following the examples provided on the official Angular page (link to the examples). I wanted the table rows to be expandable similar to the "Table with expandable rows" example on the Angula ...

Group data by date in a hashmap

In my Spring Boot backend, I am managing apps and games with a Rating Object that saves rating history in a HashMap. // Number of history by day @ElementCollection(fetch = FetchType.EAGER) private Map<String, Integer> ratingHistory = new HashMap<& ...

Encountering an npm package resolution error despite following all of the necessary requirements

error message: ERESOLVE Unable to resolve dependency Issues encountered while resolving: @ionic/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="52333c35273e332012657c667c60">[email protected]</a> Found: <a href ...

Bootstrap 4 - switch button dynamically updates icons from ">" to "<" depending on the current state

Is there a way to display an icon on the right side of a Bootstrap 4 button, such as ">" or "<", depending on whether the button is active or not? This is for an Angular-based application. The default appearance of a Bootstrap toggle button is: < ...

"Exploring the power of index signatures and methods in Typescript

What might be the reason for code producing a ts(2411) error? class Greeter { [key: string]: string | number[]; greeting: string; constructor(message: string) { this.greeting = message; } greet(): string { return "Hel ...

Is it possible that I am making a mistake when using the multi-mixin helper, which is causing an unexpected compiler error that I cannot

As I work on creating a multi-mixin helper function that takes in a map of constructors and returns an extended map with new interfaces, I come across some challenges. Let's first look at the basic base classes: class Alpha { alpha: string = &ap ...

Encountering a ReferrenceError when utilizing jQuery with TypeScript

After transitioning from using JavaScript to TypeScript, I found myself reluctant to abandon jQuery. In my search for guidance on how to integrate the two, I came across several informative websites. Working with Visual Studio 2012, here is my initial atte ...

The debate between using "this" versus "classname" to access static elements in

When working with TypeScript, I've observed that there are multiple valid approaches for accessing a static class member. class MyClass { private static readonly FOO: string = "foo"; public DoSomething(): void { console.log(MyClass.FOO);} pu ...

Should I implement jquery within angular 2, or opt for the current css/js frameworks available?

Embarking on the development of a website with Angular 2, my deadline is set within a month. I need to select a CSS/JS framework that seamlessly integrates with Angular 2. While using jQuery within Angular 2 is discouraged, I am curious if there are altern ...

Utilizing Mongoose Typescript 2 Schema with fields referencing one another in different schemas

I'm currently facing an issue as I attempt to define 2 schemas in mongoose and typescript, where each schema has a field that references the other schema. Here's an example: const Schema1: Schema = new Schema({ fieldA: Number, fieldB: Sch ...

The sequence of activities within the Primeng Multiselect component

Lately, I've encountered an issue while using the multiselect component from the primeng library in Angular. Everything was going smoothly until I noticed a strange problem with the order of events. Here is an example that showcases the issue: https:/ ...

I wonder what the response would be to this particular inquiry

I recently had an angular interview and encountered this question. The interviewer inquired about the meaning of the following code snippet in Angular: code; <app-main [type]="text"></app-main> ...

Guidelines for forming a composite type with elements?

Imagine having a convenient function that wraps a generic component with a specified constant. function wrapComponent(ComponentVariant: ComponentVariantType) { return ( <Wrapper> <ComponentVariant> <InnerComponent /> ...

Retrieving Color Values from Stylesheet in TypeScript within an Angular 2 Application

Utilizing Angular2 and Angular Material for theming, my theme scss file contains: $primary: mat-palette($mat-teal-custom, 500, 400, 900); $accent: mat-palette($mat-grey4, 500, 200, 600); There is also an alternate theme later on in the file. Within one ...

Angular2 URL fragment not recognized in Firefox

My website's main page is divided into different sections: Introduction Services Projects All the content is on the same page. To navigate to a specific section, I use Angular2 fragments in my navigation structure. Here's the HTML snippet for ...

Angular2 Eclipse: Eclipse Oxygen's HTML editor detects TypeScript errors in real-time

After installing the Eclipse Oxygen plugin for Angular2, I created a project using the Angular CLI and opened it in Eclipse. However, when trying to convert the project to an Angular project, I couldn't find the option under configuration. Instead, th ...