Skip to content

Commit bc8560e

Browse files
crisbetojosephperrott
authored andcommitted
fix(snack-bar): complete onAction observable on close (#8183)
1 parent 0719c38 commit bc8560e

File tree

2 files changed

+53
-51
lines changed

2 files changed

+53
-51
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ export class MatSnackBarRef<T> {
7979
/** Cleans up the DOM after closing. */
8080
private _finishDismiss(): void {
8181
this._overlayRef.dispose();
82+
83+
if (!this._onAction.closed) {
84+
this._onAction.complete();
85+
}
86+
8287
this._afterClosed.next();
8388
this._afterClosed.complete();
8489
}

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

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -128,22 +128,20 @@ describe('MatSnackBar', () => {
128128

129129
it('should dismiss the snack bar and remove itself from the view', async(() => {
130130
let config: MatSnackBarConfig = {viewContainerRef: testViewContainerRef};
131-
let dismissObservableCompleted = false;
131+
let dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');
132132

133133
let snackBarRef = snackBar.open(simpleMessage, undefined, config);
134134
viewContainerFixture.detectChanges();
135135
expect(overlayContainerElement.childElementCount)
136136
.toBeGreaterThan(0, 'Expected overlay container element to have at least one child');
137137

138-
snackBarRef.afterDismissed().subscribe(undefined, undefined, () => {
139-
dismissObservableCompleted = true;
140-
});
138+
snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);
141139

142140
snackBarRef.dismiss();
143141
viewContainerFixture.detectChanges(); // Run through animations for dismissal
144142

145143
viewContainerFixture.whenStable().then(() => {
146-
expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed');
144+
expect(dismissCompleteSpy).toHaveBeenCalled();
147145
expect(overlayContainerElement.childElementCount)
148146
.toBe(0, 'Expected the overlay container element to have no child elements');
149147
});
@@ -204,7 +202,7 @@ describe('MatSnackBar', () => {
204202
state to visible on entry of new snack bar`, async(() => {
205203
let config: MatSnackBarConfig = {viewContainerRef: testViewContainerRef};
206204
let snackBarRef = snackBar.open(simpleMessage, undefined, config);
207-
let dismissObservableCompleted = false;
205+
let dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');
208206

209207
viewContainerFixture.detectChanges();
210208
expect(snackBarRef.containerInstance._animationState)
@@ -214,12 +212,10 @@ describe('MatSnackBar', () => {
214212
let snackBarRef2 = snackBar.open(simpleMessage, undefined, config2);
215213

216214
viewContainerFixture.detectChanges();
217-
snackBarRef.afterDismissed().subscribe(undefined, undefined, () => {
218-
dismissObservableCompleted = true;
219-
});
215+
snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);
220216

221217
viewContainerFixture.whenStable().then(() => {
222-
expect(dismissObservableCompleted).toBe(true);
218+
expect(dismissCompleteSpy).toHaveBeenCalled();
223219
expect(snackBarRef.containerInstance._animationState)
224220
.toBe('hidden-bottom', `Expected the animation state would be 'hidden-bottom'.`);
225221
expect(snackBarRef2.containerInstance._animationState)
@@ -282,70 +278,75 @@ describe('MatSnackBar', () => {
282278

283279
it('should dismiss the snackbar when the action is called, notifying of both action and dismiss',
284280
fakeAsync(() => {
285-
let dismissObservableCompleted = false;
286-
let actionObservableCompleted = false;
287-
let snackBarRef = snackBar.open('Some content', 'Dismiss');
288-
viewContainerFixture.detectChanges();
289-
290-
snackBarRef.afterDismissed().subscribe(undefined, undefined, () => {
291-
dismissObservableCompleted = true;
292-
});
293-
snackBarRef.onAction().subscribe(undefined, undefined, () => {
294-
actionObservableCompleted = true;
295-
});
281+
const dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');
282+
const actionCompleteSpy = jasmine.createSpy('action complete spy');
283+
const snackBarRef = snackBar.open('Some content', 'Dismiss');
284+
viewContainerFixture.detectChanges();
285+
286+
snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);
287+
snackBarRef.onAction().subscribe(undefined, undefined, actionCompleteSpy);
296288

297-
let actionButton =
289+
const actionButton =
298290
overlayContainerElement.querySelector('.mat-simple-snackbar-action') as HTMLButtonElement;
299291
actionButton.click();
300292
viewContainerFixture.detectChanges();
301293
tick();
302294

303-
expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed');
304-
expect(actionObservableCompleted).toBeTruthy('Expected the snack bar to notify of action');
295+
expect(dismissCompleteSpy).toHaveBeenCalled();
296+
expect(actionCompleteSpy).toHaveBeenCalled();
305297

306298
tick(500);
307299
}));
308300

309301
it('should allow manually closing with an action', fakeAsync(() => {
310-
let dismissObservableCompleted = false;
311-
let actionObservableCompleted = false;
312-
let snackBarRef = snackBar.open('Some content');
302+
const dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');
303+
const actionCompleteSpy = jasmine.createSpy('action complete spy');
304+
const snackBarRef = snackBar.open('Some content');
313305
viewContainerFixture.detectChanges();
314306

315-
snackBarRef.afterDismissed().subscribe(undefined, undefined, () => {
316-
dismissObservableCompleted = true;
317-
});
318-
snackBarRef.onAction().subscribe(undefined, undefined, () => {
319-
actionObservableCompleted = true;
320-
});
307+
snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);
308+
snackBarRef.onAction().subscribe(undefined, undefined, actionCompleteSpy);
321309

322310
snackBarRef.closeWithAction();
323311
viewContainerFixture.detectChanges();
324312
tick();
325313

326-
expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed');
327-
expect(actionObservableCompleted).toBeTruthy('Expected the snack bar to notify of action');
314+
expect(dismissCompleteSpy).toHaveBeenCalled();
315+
expect(actionCompleteSpy).toHaveBeenCalled();
316+
317+
tick(500);
318+
}));
319+
320+
it('should complete the onAction stream when not closing via an action', fakeAsync(() => {
321+
const actionCompleteSpy = jasmine.createSpy('action complete spy');
322+
const snackBarRef = snackBar.open('Some content');
323+
viewContainerFixture.detectChanges();
324+
325+
snackBarRef.onAction().subscribe(undefined, undefined, actionCompleteSpy);
326+
snackBarRef.dismiss();
327+
viewContainerFixture.detectChanges();
328+
tick();
329+
330+
expect(actionCompleteSpy).toHaveBeenCalled();
328331

329332
tick(500);
330333
}));
331334

332335
it('should dismiss automatically after a specified timeout', fakeAsync(() => {
333-
let dismissObservableCompleted = false;
334336
let config = new MatSnackBarConfig();
335337
config.duration = 250;
336338
let snackBarRef = snackBar.open('content', 'test', config);
337-
snackBarRef.afterDismissed().subscribe(() => {
338-
dismissObservableCompleted = true;
339-
});
339+
let afterDismissSpy = jasmine.createSpy('after dismiss spy');
340+
snackBarRef.afterDismissed().subscribe(afterDismissSpy);
340341

341342
viewContainerFixture.detectChanges();
342343
tick();
343-
expect(dismissObservableCompleted).toBeFalsy('Expected the snack bar not to be dismissed');
344+
expect(afterDismissSpy).not.toHaveBeenCalled();
344345

345346
tick(1000);
346347
viewContainerFixture.detectChanges();
347348
tick();
348-
expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed');
349+
expect(afterDismissSpy).toHaveBeenCalled();
349350
}));
350351

351352
it('should clear the dismiss timeout when dismissed before timeout expiration', fakeAsync(() => {
@@ -411,24 +412,20 @@ describe('MatSnackBar', () => {
411412
});
412413

413414
it('should allow manually closing with an action', fakeAsync(() => {
414-
let dismissObservableCompleted = false;
415-
let actionObservableCompleted = false;
415+
const dismissCompleteSpy = jasmine.createSpy('dismiss complete spy');
416+
const actionCompleteSpy = jasmine.createSpy('action complete spy');
416417
const snackBarRef = snackBar.openFromComponent(BurritosNotification);
417418
viewContainerFixture.detectChanges();
418419

419-
snackBarRef.afterDismissed().subscribe(undefined, undefined, () => {
420-
dismissObservableCompleted = true;
421-
});
422-
snackBarRef.onAction().subscribe(undefined, undefined, () => {
423-
actionObservableCompleted = true;
424-
});
420+
snackBarRef.afterDismissed().subscribe(undefined, undefined, dismissCompleteSpy);
421+
snackBarRef.onAction().subscribe(undefined, undefined, actionCompleteSpy);
425422

426423
snackBarRef.closeWithAction();
427424
viewContainerFixture.detectChanges();
428425
tick();
429426

430-
expect(dismissObservableCompleted).toBeTruthy('Expected the snack bar to be dismissed');
431-
expect(actionObservableCompleted).toBeTruthy('Expected the snack bar to notify of action');
427+
expect(dismissCompleteSpy).toHaveBeenCalled();
428+
expect(actionCompleteSpy).toHaveBeenCalled();
432429

433430
tick(500);
434431
}));

0 commit comments

Comments
 (0)