@@ -29,7 +29,7 @@ import {
29
29
} from '@angular/core' ;
30
30
import { MatSnackBarConfig , _SnackBarContainer } from '@angular/material/snack-bar' ;
31
31
import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations' ;
32
- import { MDCSnackbarAdapter , MDCSnackbarFoundation } from '@material/snackbar' ;
32
+ import { MDCSnackbarAdapter , MDCSnackbarFoundation , cssClasses } from '@material/snackbar' ;
33
33
import { Platform } from '@angular/cdk/platform' ;
34
34
import { Observable , Subject } from 'rxjs' ;
35
35
@@ -98,10 +98,7 @@ export class MatSnackBarContainer
98
98
addClass : ( className : string ) => this . _setClass ( className , true ) ,
99
99
removeClass : ( className : string ) => this . _setClass ( className , false ) ,
100
100
announce : ( ) => { } ,
101
- notifyClosed : ( ) => {
102
- this . _onExit . next ( ) ;
103
- this . _mdcFoundation . destroy ( ) ;
104
- } ,
101
+ notifyClosed : ( ) => this . _finishExit ( ) ,
105
102
notifyClosing : ( ) => { } ,
106
103
notifyOpened : ( ) => this . _onEnter . next ( ) ,
107
104
notifyOpening : ( ) => { } ,
@@ -184,16 +181,24 @@ export class MatSnackBarContainer
184
181
}
185
182
186
183
exit ( ) : Observable < void > {
187
- // It's common for snack bars to be opened by random outside calls like HTTP requests or
188
- // errors. Run inside the NgZone to ensure that it functions correctly.
189
- this . _ngZone . run ( ( ) => {
190
- this . _exiting = true ;
191
- this . _mdcFoundation . close ( ) ;
184
+ const classList = this . _elementRef . nativeElement . classList ;
192
185
193
- // If the snack bar hasn't been announced by the time it exits it wouldn't have been open
194
- // long enough to visually read it either, so clear the timeout for announcing.
195
- clearTimeout ( this . _announceTimeoutId ) ;
196
- } ) ;
186
+ // MDC won't complete the closing sequence if it starts while opening hasn't finished.
187
+ // If that's the case, destroy immediately to ensure that our stream emits as expected.
188
+ if ( classList . contains ( cssClasses . OPENING ) || ! classList . contains ( cssClasses . OPEN ) ) {
189
+ this . _finishExit ( ) ;
190
+ } else {
191
+ // It's common for snack bars to be opened by random outside calls like HTTP requests or
192
+ // errors. Run inside the NgZone to ensure that it functions correctly.
193
+ this . _ngZone . run ( ( ) => {
194
+ this . _exiting = true ;
195
+ this . _mdcFoundation . close ( ) ;
196
+ } ) ;
197
+ }
198
+
199
+ // If the snack bar hasn't been announced by the time it exits it wouldn't have been open
200
+ // long enough to visually read it either, so clear the timeout for announcing.
201
+ clearTimeout ( this . _announceTimeoutId ) ;
197
202
198
203
return this . _onExit ;
199
204
}
@@ -236,6 +241,13 @@ export class MatSnackBarContainer
236
241
}
237
242
}
238
243
244
+ /** Finishes the exit sequence of the container. */
245
+ private _finishExit ( ) {
246
+ this . _onExit . next ( ) ;
247
+ this . _onExit . complete ( ) ;
248
+ this . _mdcFoundation . destroy ( ) ;
249
+ }
250
+
239
251
/**
240
252
* Starts a timeout to move the snack bar content to the live region so screen readers will
241
253
* announce it.
0 commit comments