From e44482b5c428e95e4517fd266a8a4565670e122f Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sat, 24 Dec 2016 13:26:02 +0200 Subject: [PATCH] fix(snack-bar): prevent error when opening multiple snack bars in fast succession Fixes a runtime error being thrown by Angular when opening multiple snack bars, that have a timeout, in quick succession. The fix waits for the zone to settle before firing the final callbacks. **Note on testing:** This change is missing a unit test, because I couldn't find a way to trigger the error during tests, however the approach is similar to #2219. Fixes #2390. --- src/lib/snack-bar/snack-bar-container.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/lib/snack-bar/snack-bar-container.ts b/src/lib/snack-bar/snack-bar-container.ts index 2a88f0e453ee..61d1ec646d42 100644 --- a/src/lib/snack-bar/snack-bar-container.ts +++ b/src/lib/snack-bar/snack-bar-container.ts @@ -92,11 +92,9 @@ export class MdSnackBarContainer extends BasePortalHost implements OnDestroy { /** Handle end of animations, updating the state of the snackbar. */ onAnimationEnd(event: AnimationTransitionEvent) { if (event.toState === 'void' || event.toState === 'complete') { - this._ngZone.run(() => { - this.onExit.next(); - this.onExit.complete(); - }); + this._completeExit(); } + if (event.toState === 'visible') { this._ngZone.run(() => { this.onEnter.next(); @@ -131,8 +129,14 @@ export class MdSnackBarContainer extends BasePortalHost implements OnDestroy { * Makes sure the exit callbacks have been invoked when the element is destroyed. */ ngOnDestroy() { - // Wait for the zone to settle before removing the element. Helps prevent - // errors where we end up removing an element which is in the middle of an animation. + this._completeExit(); + } + + /** + * Waits for the zone to settle before removing the element. Helps prevent + * errors where we end up removing an element which is in the middle of an animation. + */ + private _completeExit() { this._ngZone.onMicrotaskEmpty.first().subscribe(() => { this.onExit.next(); this.onExit.complete();