From 6e58d1e3cefc52e1f4156ceb98e660133b842a49 Mon Sep 17 00:00:00 2001 From: Sven Reglitzki Date: Mon, 29 May 2017 11:11:30 +0200 Subject: [PATCH] fix(snack-bar): Clear duration timeout on dismiss When a duration is passed to MdSnackBar.prototype.openFromComponent(), a timeout is created. This timeout is now cleared when dismissing the snackbar. Fixes #4859 --- 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 c4e45c59a67f..3f889f2b67f0 100644 --- a/src/lib/snack-bar/snack-bar-ref.ts +++ b/src/lib/snack-bar/snack-bar-ref.ts @@ -31,6 +31,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) { @@ -47,6 +53,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 76e085c494c5..e87c53b0ed84 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, { viewContainerRef: testViewContainerRef, diff --git a/src/lib/snack-bar/snack-bar.ts b/src/lib/snack-bar/snack-bar.ts index 473bd0ef8925..c9a413352148 100644 --- a/src/lib/snack-bar/snack-bar.ts +++ b/src/lib/snack-bar/snack-bar.ts @@ -81,7 +81,7 @@ export class MdSnackBar { // If a dismiss timeout is provided, set up dismiss based on after the snackbar is opened. if (config.duration > 0) { snackBarRef.afterOpened().subscribe(() => { - setTimeout(() => snackBarRef.dismiss(), config.duration); + snackBarRef._dismissAfter(config.duration); }); }