I am facing a strange issue with Angular Material Tabs and hope someone can help me explain what is going on. https://stackblitz.com/edit/angular-ivy-yttids
I have a mat-tab component with 3 tabs. My goal is to call an external service as soon as the user clicks on any tab for the first time and display the results in tab contents.
On page initialization, tabs are generated and Tab-1 comes already selected. And if I click tabs in a certain order (Tab3->Tab2-Tab1), everything is just as expected. But if I click Tab2 first, after page refresh, it is not activated but focus passes on Tab-3 automatically for no reason. The behavior repeats just once more on Tab1 and back to normal, meaning I can activate the tab I click.
Here is another strange order of clicks you might want to check yourself:
I'd appreciate it if you can have a look at the link and let me know if you can figure out what's really going on.
Thanks
Well, you're actually changing the section
variable, which is used to render the tab. (inside your *ngFor).
Changing this section will force mat-tab
to reload the component which result in a funny bug (sorry, cannot explain better than that).
My option is to add a trackBy function, so you tell angular to only reload the element that did changed.
There the solution in a stackblirtz
trackByIndexFn(index: any, item: any) {
return index
}
<div *ngIf="input">
<mat-tab-group
#tabs
mat-align-tabs="center"
animationDuration="0ms"
[(selectedIndex)]="selectedIndexBinding"
(selectedIndexChange)="onTabChanged($event)"
>
<mat-tab
*ngFor="let section of parts; index as tabNo; trackBy: trackByIndexFn" <!-- Here, I use the trackBy function -->
>
<ng-template mat-tab-label>
<span class="tab-heading">Tab {{ tabNo + 1 }}</span>
</ng-template>
<ng-template matTabContent>
<br />
<div *ngFor="let data of section; index as i">
<div style="text-align:center">{{ data }}</div>
<br />
</div>
</ng-template>
</mat-tab>
</mat-tab-group>
</div>
you're not only avoiding the bug, but also optimizing your code ;)