question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Tabs] Toggling quickly can cause content to be duplicated

See original GitHub issue

Bug, feature request, or proposal:

I have had some trouble reproducing this one reliably (it seems to occur more often on my app than in reproductions) but there seems to be a race condition related to the rendering of tab content when it is lazy-loaded.

What is the expected behavior?

Tab content should only be displayed once.

What is the current behavior?

Toggling tabs very quickly (using arrow keys + space bar) can cause tab content to be drawn multiple times.

What are the steps to reproduce?

StackBlitz: https://stackblitz.com/edit/angular-material2-issue-h6pgut?file=app%2Fapp.component.ts

I am intentionally trying to be awkward in terms of timing (ie. setting the selectedTabIndex in a timeout), but this behaviour still should not happen.

I have recorded a reproduction in this video: https://gfycat.com/ReadyFairBasil Note that at the start there is only one instance of each tab’s content but by the end the second tab’s content is duplicated.

What is the use-case or motivation for changing an existing behavior?

Bug

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Latest StackBlitz (Angular 6-rc2, Material 6-rc1)

Is there anything else we should know?

I could only reproduce by using lazy-loaded tabs + NgForTrackBy + OnPush + window.setTimeout, but these may not be necessary. I also had to use keyboard selection to toggle fast enough to trigger the issue.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:5
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

6reactions
manklucommented, Oct 24, 2018

@benelliott The problem is the animation. If you disable it, the problem disappears.

<mat-tab-group [@.disabled]="true">
  <mat-tab *ngFor="let tab of tabs" [label]="tab">
    <div *matTabContent class="content">
      {{tab}}
    </div>
  </mat-tab>
</mat-tab-group>

This would also fit the ~500ms observation from @xyz247.

Possibly related to https://github.com/angular/angular/issues/26133

3reactions
joelcoxokccommented, Sep 5, 2019

Simple Workaround

This only works if you have only one base element inside each tabContent template

For Example

<mat-tab-group>
    <mat-tab>
        <ng-template matTabContent>
            <div class="tab-container">
                <!-- Content goes here -->
            </div>
        </ng-template>
    </mat-tab>
    <mat-tab>
        <ng-template matTabContent>
            <div class="tab-container">
                <!-- Content goes here -->
            </div>
        </ng-template>
    </mat-tab>
</mat-tab-group>

Listen to the output on the <mat-tab-group> for (animationDone)

<mat-tab-group (animationDone)="onTabAnimationDone()">

On Animation done, we want to look for any additional .tab-containers that have been rendered inside the active tab.

export class MyComponent {
    constructor(private elementRef: ElementRef) {}

    public onTabAnimationDone(): void {
        const inactiveTabs = this.elementRef.nativeElement.querySelectorAll(
            '.mat-tab-body-active .mat-tab-body-content > .tab-container:not(:first-child)'
        );
        
        inactiveTabs.forEach(tab => tab.remove());
    }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Why does dynamically creating togglable tabs cause duplicate ...
Upon creating a new tab, it appears that the previously clicked tab's content (within the div containing ng-switch-when ) is duplicated.
Read more >
Tabs and duplicate content? | SEO Forum - Moz
Does this mean that our content is being duplicated onto another page? ... I would simply make sure that the link is rewritten...
Read more >
Prevent or create duplicate tabs in Safari on Mac
Duplicate a tab​​ In the Safari app on your Mac, Control-click a tab or pin, then choose Duplicate Tab.
Read more >
tabs.duplicate() - Mozilla - MDN Web Docs
A Promise that will be fulfilled with a tabs.Tab object containing details about the duplicated tab. The Tab object only contains url ,...
Read more >
Clutter Free - Prevent duplicate tabs
Reduce tab clutter - prevent duplicate tabs, quickly search & switch tabs, and more... ** Automatically detect and close duplicate tabs ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found