Transferring data from a parent component to a child component nestled inside a tabpanel of a tabview

In the given scenario, there is a child component nested in a tab panel defined within the parent component. This setup allows for multiple tab panels and consequently multiple instances of the child component being nested in each tab panel. The goal is to assign a specific value to the child component based on the active tab panel. However, the issue arises when regardless of which tab is selected, the value only updates for Tab 0. To illustrate this problem more effectively, here is a simplified version of the existing code. A functional example can be viewed here: https://stackblitz.com/edit/angular-fd7b3j

To see the issue firsthand, click 'Create Tabs' to generate several tabs and then make Tab 3 the current tab. Subsequently, clicking 'Add One' should ideally update the element value to 4. However, the actual outcome is that the element value in Tab 0 gets updated to 1. Is it possible to direct this action to the correct tab? If so, how?

app.component.html

<p-button label="Create Tabs" (onClick)="handleClick()"></p-button>
<p-button label="AddOne" (onClick)="AddOne()"></p-button>
<p-tabView (onChange)=setIndex($event) [(activeIndex)]="index">
  <p-tabPanel #panel [header]="elememt" *ngFor="let elememt of counterList; let i = index" [selected]="i == currentIndex" >
    <app-main #main [element]="counterList[i]"></app-main>
  </p-tabPanel>
</p-tabView>

app.component.ts

import { Component, ViewChild } from '@angular/core';
import { MainComponent } from './main/main.component';
import { TabViewNav, TabView } from 'primeng/tabview';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'tabViews';
  currentIndex = 0;
  @ViewChild('main') main: MainComponent;

  @ViewChild ('panel') panel: TabView;
  counter = 0;
  counterList: number[] = [];

  index = 0;

  handleClick(event: Event) {
      this.counterList = [...this.counterList, this.counter];

      setTimeout(() => {
        this.index = this.counter;
        this.currentIndex = this.counter;
        this.counter = this.counter + 1;
    }, 100);
  }

  setIndex(event) {
    this.currentIndex = event.index;
  }

  AddOne() {
    console.log(this.index);
    this.main.element = this.main.element + 1;
  }
}

main.component.ts

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-main',
  templateUrl: './main.component.html',
  styleUrls: ['./main.component.css']
})
export class MainComponent implements OnInit {
  @Input() element: number;

  constructor() { }

  ngOnInit() {
  }
}

main.component.html

{{element}}

Answer №1

the situation occurred because you utilized ViewChild, which only provides a single reference to the first component. Instead, try using ViewChildren to retrieve an array of your child components, allowing you to access each of them by their index. Don't forget to update the currentIndex based on the onChange event of the tab view. Have fun coding! :))))

import { Component, ViewChild, ViewChildren, QueryList  } from '@angular/core';
import { MainComponent } from './main/main.component';
import { TabViewNav, TabView } from 'primeng/tabview';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: './app.component.css'
})
export class AppComponent {
  title = 'tabViews';
  currentIndex = 0;
  @ViewChildren('main') main: QueryList<MainComponent>;

  @ViewChild ('panel') panel: TabView;
  counter = 0;
  counterList: number[] = [];

  tabIndex = 0;

  handleClick(event: Event) {
      this.counterList = [...this.counterList, this.counter];
      setTimeout(() => {
      this.currentIndex = this.counter;
      this.counter = this.counter + 1;     
     }, 100);
  }

  AddOne() {
    console.log(this.tabIndex);
   this.main.toArray()[this.currentIndex].element = this.main.toArray()[this.currentIndex].element  + 1;
  }  
}

Answer №2

Here is an updated version of the AddOne function:

AddOne() {
    Increment the value at the current index in the counter list by 1;
}

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

Steps to access email template through an Excel web add-in

Currently, I am developing a new addin that aims to extract data from Excel and insert it into a word document. The final step would be attaching this document to an email in Outlook. While I have managed to achieve this using Power Automate, I prefer to ...

Stop the reactive form from automatically submitting and instead manually send a POST request to the server

I'm facing a small issue with my form submission. When I try to submit an empty form, it sends a post request to my server, and I'm unsure how to prevent that from happening. Below is my form structure: <form class="form-horizontal" [ ...

Using services in Angular 6 CLI with dynamically added components

One of my recent projects involved creating a directive in Angular 6 called 'DeleteDirective' and integrating it with a service called 'DeleteService' to enable the deletion of items from the application. Once an item is deleted (handle ...

Enable the generation of scss.d.ts files with Next.js

I'm currently working on a project that requires the generation of .d.ts files for the scss it produces. Instead of manually creating these files, I have integrated css-modules-typescript-loader with Storybook to automate this process. However, I am ...

Developing an npm module encapsulating API contracts for seamless integration with front-end applications using Typescript

I am curious if Typescript supports this specific idea, and I could use some advice on how to make it work. In my project, there's a frontend application and a backend REST API with clear contract classes for Inputs and Outputs. These classes outline ...

The Angular 2 HTTP GET method is throwing a type 3 error when trying to access the

i am encountering an issue while trying to retrieve a response from my asp.core api within Angular 2. The error message received is: "Object { _body: error, status: 0, ok: false, statusText: "", headers: {…}, type: 3, url: null }" Component: import { C ...

What is the reason behind the auth() function in Auth.js returning a null user object?

Utilizing Auth.js credentials provider for user sign-ins in a Next.js application has proven successful. The auth() function now returns a non-null object upon signing in, as opposed to returning null previously. // when not signed in const session = await ...

Angular: Failure in receiving EventEmitter's event with .subscribe method

My current challenge involves handling an event coming from NgLoopDirective within the method EV of NgDNDirective. I am attempting to achieve this by passing the EventEmitter object by reference and then calling .subscribe() as shown in the code snippet be ...

tsc will automatically incorporate additional files

I'm grappling with a frustrating issue related to tsc that's really getting to me. The problem involves having a file b.ts in the src folder, and another file a.ts in the project root folder. Here is an excerpt of my tsconfig file: { "comp ...

What is the best way to update my TypeScript array with new values in real-time?

Looking to dynamically populate my pieChartColors array so that it resembles the following structure: public pieChartColors:Array<Color> = [ { backgroundColor: '#141C48' }, { backgroundColor: '#FF0000' }, { backgroundColor: ...

The silent refresh functionality is currently not functioning as expected in Angular's OAuth OIDC implementation

In my Angular SPA, I am attempting to silently refresh the access token. The authentication with ADFS has been successfully completed and everything is functioning properly. Below is the configuration that I have implemented: oauthService.configure({ ...

Comparing the Calculation of CSS Selector Specificity: Class versus Elements [archived]

Closed. This question requires additional information for debugging purposes. It is not currently accepting answers. ...

How can I ensure I am receiving real-time updates from a Resolver Service by subscribing and staying in sync with the

How can I effectively implement this code without encountering an error? "Property 'resolve' in type 'DocumentaryResolverService' is not assignable to the same property in base type 'Resolve'." import { Documentary } from ...

Encountering issues when passing a string as query parameters

How can I successfully pass a string value along with navigation from one component to another using query parameters? Component1: stringData = "Hello"; this.router.navigate(['component2'], { queryParams: stringData }); Component2: ...

Unable to perform module augmentation in TypeScript

Following the guidelines provided, I successfully added proper typings to my react-i18next setup. The instructions can be found at: However, upon creating the react-i18next.d.ts file, I encountered errors concerning unexported members within the react-i18 ...

What scenarios call for utilizing "dangerouslySetInnerHTML" in my React code?

I am struggling to grasp the concept of when and why to use the term "dangerous," especially since many programmers incorporate it into their codes. I require clarification on the appropriate usage and still have difficulty understanding, as my exposure ha ...

Discovering JSON data in Angular 4

I am working with a JSON data format retrieved from (this.url) { "user": [ { "id": "1", "name": "root", "password": "root" }, { "id": "2", "name": "clienttest", ...

Issue with displaying Angular chart only resolves after resizing window following routing updates

Hey there! I'm having trouble getting my chart to show up after adding routing to my 3 tabs. Previously, without routing, everything worked fine. Now, the graph only appears after resizing the window. The chart is using PrimeNG chart with the Chart.js ...

What causes TypeScript to interpret an API call as a module and impact CSS? Encountering a Next.js compilation error

My website development process hit a roadblock when I tried integrating Material Tailwind into my project alongside Next.js, Typescript, and Tailwind CSS. The compilation error that popped up seemed unrelated to the changes, leaving me baffled as to what c ...

Why does "excess property checking" seem pleased when I utilize a key from set A or set B, even though "keyof (A|B)" is consistently "never"?

I am diving deeper into Typescript types and encountering some puzzling behavior: interface Person { name: string; } interface Lifespan { birth: number; death?: number; } let k: keyof (Person | Lifespan); //k is never let test1: Person | Life ...