Search code examples
angulartypescriptobservable

Subscribe() method getting called multiple times on click of button in Angular 8


I am stuck while developing Angular 8 application due to an issue. There are two buttons on UI. When I hit a button, an event gets triggered which provides me its index position in array packageHeaders.

<p-tabView (onChange)="tabChange($event)">
          <p-tabPanel *ngFor="let tabHeader of packageHeaders" [header]=tabHeader>
                //few html lines
          </p-tabPanel>  
</p-tabView>

Based on the index, I am rendering package data in 3-4 different components and performing calculations as per business rules/requirement.

To make the selected index available in all the components, I have declared a BehaviourSubject in service class and passing the index to it. Then after, I am releasing it as observable so that my components can subscribe it. Below is service class code snippet:

public tabIndex = new BehaviorSubject<number>(0);

findTabClicked(changeInTabSelection: number) {
    this.tabIndex.next(changeInTabSelection);
  }

  getSelectedTab(): Observable<number> {
    return this.tabIndex.asObservable();
  }

In my components, I am subscribing it to get the latest selected value. Eg:

 this.service.getSelectedTab().subscribe((selectedTabIndex) => {
      this.packageTypeInUse(selectedTabIndex);
      this.calculateTotalOnQuantityChange(this.regularIndex[selectedTabIndex]);
    });

I am unsubscribing it as well in ngOnDestroy() lifecycle hook. In template, I am using for loop to show the line Items *ngFor="let item of packageLineItems[tabIndex]

So, based on this index, i am displaying a list of line items on UI. I can modify the item values. I can also traverse to other tabHeader by clicking the button.

There are two problems:

  1. The above Subscribe method is getting called twice in all the components.
  2. On debugging the code, I come to know that,on first subscription, my array packageLineItems[tabIndex] had the modified values but it gets override by initial array values on second subscription.

I have initialized the array on ngOnInit(). Just to be sure, I have also verified that On changing the tab headers, ngOnInit() is not getting called. Not sure, how the array is getting reset to initial values automatically on second unwanted subscription call.


Solution

  • Finally, the issue is resolved. It was a silly mistake yet a good understanding. The HTML snippet which I shared in question has for-loop. Instead of closing the html tag <p-tabPanel> like below, we have closed it after declaring child components into the loop.

    <p-tabPanel *ngFor="let tabHeader of this.packageHeaders" [header]=tabHeader></p-tabPanel>
    

    This is the reason why components were getting initialized multiple times and same with the subscribers.