From 146160c4ea285ffe8734d4f80d7aa46f4ab3427e Mon Sep 17 00:00:00 2001 From: Sven Reglitzki Date: Fri, 23 Jun 2017 22:22:38 +0200 Subject: [PATCH] fix(snackbar): clear timeout upon dismiss (#4860) --- src/lib/snack-bar/snack-bar-ref.ts | 12 ++++++++++++ src/lib/snack-bar/snack-bar.spec.ts | 14 ++++++++++++++ src/lib/snack-bar/snack-bar.ts | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/lib/snack-bar/snack-bar-ref.ts b/src/lib/snack-bar/snack-bar-ref.ts index 67f422a4e345..6028a9c2416b 100644 --- a/src/lib/snack-bar/snack-bar-ref.ts +++ b/src/lib/snack-bar/snack-bar-ref.ts @@ -39,6 +39,12 @@ export class MdSnackBarRef { /** Subject for notifying the user that the snack bar action was called. */ private _onAction: Subject = new Subject(); + /** + * Timeout ID for the duration setTimeout call. Used to clear the timeout if the snackbar is + * dismissed before the duration passes. + */ + private _durationTimeoutId: number; + constructor(instance: T, containerInstance: MdSnackBarContainer, private _overlayRef: OverlayRef) { @@ -55,6 +61,12 @@ export class MdSnackBarRef { if (!this._afterClosed.closed) { this.containerInstance.exit(); } + clearTimeout(this._durationTimeoutId); + } + + /** Dismisses the snack bar after some duration */ + _dismissAfter(duration: number): void { + this._durationTimeoutId = setTimeout(() => this.dismiss(), duration); } /** Marks the snackbar action clicked. */ diff --git a/src/lib/snack-bar/snack-bar.spec.ts b/src/lib/snack-bar/snack-bar.spec.ts index be930ff78b6c..882a82191ab1 100644 --- a/src/lib/snack-bar/snack-bar.spec.ts +++ b/src/lib/snack-bar/snack-bar.spec.ts @@ -328,6 +328,20 @@ describe('MdSnackBar', () => { expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed'); })); + it('should clear the dismiss timeout when dismissed before timeout expiration', fakeAsync(() => { + let config = new MdSnackBarConfig(); + config.duration = 1000; + snackBar.open('content', 'test', config); + + setTimeout(() => snackBar.dismiss(), 500); + + tick(600); + viewContainerFixture.detectChanges(); + flushMicrotasks(); + + expect(viewContainerFixture.isStable()).toBe(true); + })); + it('should add extra classes to the container', () => { snackBar.open(simpleMessage, simpleActionLabel, { extraClasses: ['one', 'two'] }); viewContainerFixture.detectChanges(); diff --git a/src/lib/snack-bar/snack-bar.ts b/src/lib/snack-bar/snack-bar.ts index 9e1c6f39aedb..f18f067f3b9c 100644 --- a/src/lib/snack-bar/snack-bar.ts +++ b/src/lib/snack-bar/snack-bar.ts @@ -89,7 +89,7 @@ export class MdSnackBar { // If a dismiss timeout is provided, set up dismiss based on after the snackbar is opened. if (config.duration && config.duration > 0) { snackBarRef.afterOpened().subscribe(() => { - setTimeout(() => snackBarRef.dismiss(), config!.duration); + snackBarRef._dismissAfter(config!.duration!); }); }