Skip to content

Commit

Permalink
feat(modal): support for promises in beforeDismiss hook
Browse files Browse the repository at this point in the history
NgbModalOptions#beforeDismiss may now return a promise. The modal is closed if the promise is resolved with false or if it is rejected.

Closes #2340
  • Loading branch information
planser authored and pkozlowski-opensource committed May 18, 2018
1 parent 3a7ca58 commit cca789f
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 6 deletions.
23 changes: 20 additions & 3 deletions src/modal/modal-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,31 @@ export class NgbModalRef {
}
}

private _dismiss(reason?: any) {
this._reject(reason);
this._removeModalElements();
}

/**
* Can be used to dismiss a modal, passing an optional reason.
*/
dismiss(reason?: any): void {
if (this._windowCmptRef) {
if (!this._beforeDismiss || this._beforeDismiss() !== false) {
this._reject(reason);
this._removeModalElements();
if (!this._beforeDismiss) {
this._dismiss(reason);
} else {
const dismiss = this._beforeDismiss();
if (dismiss && dismiss.then) {
dismiss.then(
result => {
if (result !== false) {
this._dismiss(reason);
}
},
() => {});
} else if (dismiss !== false) {
this._dismiss(reason);
}
}
}
}
Expand Down
44 changes: 43 additions & 1 deletion src/modal/modal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
Injector
} from '@angular/core';
import {CommonModule} from '@angular/common';
import {TestBed, ComponentFixture} from '@angular/core/testing';
import {TestBed, ComponentFixture, async} from '@angular/core/testing';

import {NgbModalModule, NgbModal, NgbActiveModal, NgbModalRef} from './modal.module';

Expand Down Expand Up @@ -393,6 +393,48 @@ describe('ngb-modal', () => {
expect(fixture.nativeElement).not.toHaveModal();
});

it('should not dismiss when the returned promise is resolved with false', async(() => {
const modalInstance = fixture.componentInstance.openTplDismiss({beforeDismiss: () => Promise.resolve(false)});
fixture.detectChanges();
expect(fixture.nativeElement).toHaveModal();

(<HTMLElement>document.querySelector('button#dismiss')).click();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(fixture.nativeElement).toHaveModal();

modalInstance.close();
fixture.detectChanges();
expect(fixture.nativeElement).not.toHaveModal();
});
}));

it('should not dismiss when the returned promise is rejected', async(() => {
const modalInstance = fixture.componentInstance.openTplDismiss({beforeDismiss: () => Promise.reject('error')});
fixture.detectChanges();
expect(fixture.nativeElement).toHaveModal();

(<HTMLElement>document.querySelector('button#dismiss')).click();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(fixture.nativeElement).toHaveModal();

modalInstance.close();
fixture.detectChanges();
expect(fixture.nativeElement).not.toHaveModal();
});
}));

it('should dismiss when the returned promise is not resolved with false', async(() => {
fixture.componentInstance.openTplDismiss({beforeDismiss: () => Promise.resolve()});
fixture.detectChanges();
expect(fixture.nativeElement).toHaveModal();

(<HTMLElement>document.querySelector('button#dismiss')).click();
fixture.detectChanges();
fixture.whenStable().then(() => { expect(fixture.nativeElement).not.toHaveModal(); });
}));

it('should dismiss when the callback is not defined', () => {
fixture.componentInstance.openTplDismiss({});
fixture.detectChanges();
Expand Down
5 changes: 3 additions & 2 deletions src/modal/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ export interface NgbModalOptions {

/**
* Function called when a modal will be dismissed.
* If this function returns false, the modal is not dismissed.
* If this function returns false, the promise is resolved with false or the promise is rejected, the modal is not
* dismissed.
*/
beforeDismiss?: () => boolean;
beforeDismiss?: () => boolean | Promise<boolean>;

/**
* To center the modal vertically (false by default).
Expand Down

0 comments on commit cca789f

Please sign in to comment.