Skip to content

Commit 85caa54

Browse files
Sven Reglitzkisv2dev
authored andcommitted
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
1 parent 12d6e96 commit 85caa54

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

src/lib/snack-bar/snack-bar-ref.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ export class MdSnackBarRef<T> {
3131
/** Subject for notifying the user that the snack bar action was called. */
3232
private _onAction: Subject<any> = new Subject();
3333

34+
/**
35+
* Timeout ID for the duration setTimeout call. Used to clear the timeout if the snackbar is
36+
* dismissed before the duration passes.
37+
*/
38+
private _durationTimeoutId: number;
39+
3440
constructor(instance: T,
3541
containerInstance: MdSnackBarContainer,
3642
private _overlayRef: OverlayRef) {
@@ -47,6 +53,12 @@ export class MdSnackBarRef<T> {
4753
if (!this._afterClosed.closed) {
4854
this.containerInstance.exit();
4955
}
56+
clearTimeout(this._durationTimeoutId);
57+
}
58+
59+
/** Dismisses the snack bar after some duration */
60+
_dismissAfter(duration: number): void {
61+
this._durationTimeoutId = setTimeout(() => this.dismiss(), duration);
5062
}
5163

5264
/** Marks the snackbar action clicked. */

src/lib/snack-bar/snack-bar.spec.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import {
55
TestBed,
66
fakeAsync,
77
flushMicrotasks,
8-
tick
8+
tick,
9+
flush
910
} from '@angular/core/testing';
1011
import {NgModule, Component, Directive, ViewChild, ViewContainerRef} from '@angular/core';
1112
import {CommonModule} from '@angular/common';
@@ -328,6 +329,19 @@ describe('MdSnackBar', () => {
328329
expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed');
329330
}));
330331

332+
it('should clear the dismiss timeout when dismissed before timeout expiration', fakeAsync(() => {
333+
let config = new MdSnackBarConfig();
334+
config.duration = 1000;
335+
let snackBarRef = snackBar.open('content', 'test', config);
336+
337+
setTimeout(() => snackBar.dismiss(), 500);
338+
339+
const elapsed = flush();
340+
viewContainerFixture.detectChanges();
341+
flushMicrotasks();
342+
expect(elapsed).toEqual(500, 'The timeout microtask should have been cancelled.');
343+
}));
344+
331345
it('should add extra classes to the container', () => {
332346
snackBar.open(simpleMessage, simpleActionLabel, {
333347
viewContainerRef: testViewContainerRef,

src/lib/snack-bar/snack-bar.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export class MdSnackBar {
8181
// If a dismiss timeout is provided, set up dismiss based on after the snackbar is opened.
8282
if (config.duration > 0) {
8383
snackBarRef.afterOpened().subscribe(() => {
84-
setTimeout(() => snackBarRef.dismiss(), config.duration);
84+
snackBarRef._dismissAfter(config.duration);
8585
});
8686
}
8787

0 commit comments

Comments
 (0)