Skip to content

Commit 320504c

Browse files
feat(dialog-controller): pass close result to lifecycle hooks
BREAKING CHANGE - DialogController.prototype.error wraps the passed reason in DialogCloseError
1 parent 42ad7f3 commit 320504c

File tree

4 files changed

+46
-14
lines changed

4 files changed

+46
-14
lines changed

src/dialog-close-error.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* The error is thrown when the dialog is closed with the `DialogController.prototype.error` method.
3+
*/
4+
export interface DialogCloseError extends Error {
5+
reason: any;
6+
}
7+
8+
/**
9+
* @internal
10+
*/
11+
export function createDialogCloseError(reason: any): DialogCloseError {
12+
const error = new Error() as DialogCloseError;
13+
error.reason = reason;
14+
return error;
15+
}

src/dialog-controller.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Renderer } from './renderer';
33
import { DialogCancelableOperationResult, DialogCloseResult, DialogCancelResult } from './dialog-result';
44
import { DialogSettings } from './dialog-settings';
55
import { invokeLifecycle } from './lifecycle';
6+
import { createDialogCloseError, DialogCloseError } from './dialog-close-error';
67
import { createDialogCancelError } from './dialog-cancel-error';
78

89
/**
@@ -45,8 +46,8 @@ export class DialogController {
4546
/**
4647
* @internal
4748
*/
48-
public releaseResources(dialogResult?: any): Promise<void> {
49-
return invokeLifecycle(this.controller.viewModel || {}, 'deactivate', dialogResult)
49+
public releaseResources(result: DialogCloseResult | DialogCloseError): Promise<void> {
50+
return invokeLifecycle(this.controller.viewModel || {}, 'deactivate', result)
5051
.then(() => this.renderer.hideDialog(this))
5152
.then(() => { this.controller.unbind(); });
5253
}
@@ -79,11 +80,12 @@ export class DialogController {
7980

8081
/**
8182
* Closes the dialog with an error result.
82-
* @param message An error message.
83+
* @param reason A reason for closing with an error.
8384
* @returns Promise An empty promise object.
8485
*/
85-
public error(message: any): Promise<void> {
86-
return this.releaseResources().then(() => { this.reject(message); });
86+
public error(reason: any): Promise<void> {
87+
const closeError = createDialogCloseError(reason);
88+
return this.releaseResources(closeError).then(() => { this.reject(closeError); });
8789
}
8890

8991
/**
@@ -119,6 +121,6 @@ export class DialogController {
119121
this.closePromise = undefined;
120122
return Promise.reject(reason);
121123
});
122-
});
124+
});
123125
}
124126
}

src/interfaces.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { DialogCloseError } from './dialog-close-error';
2+
import { DialogCloseResult } from './dialog-result';
13
/**
24
* An optional interface describing the dialog canActivate convention.
35
*/
@@ -29,7 +31,7 @@ export interface DialogComponentCanDeactivate {
2931
* To cancel the closing of the dialog return false or a promise that resolves to false.
3032
* Any other returned value is coerced to true.
3133
*/
32-
canDeactivate(): boolean | Promise<boolean> | PromiseLike<boolean>;
34+
canDeactivate(result: DialogCloseResult): boolean | Promise<boolean> | PromiseLike<boolean>;
3335
}
3436

3537
/**
@@ -39,5 +41,5 @@ export interface DialogComponentDeactivate {
3941
/**
4042
* Implement this hook if you want to perform custom logic when the dialog is being closed.
4143
*/
42-
deactivate(): void | Promise<void> | PromiseLike<void>;
44+
deactivate(result: DialogCloseResult | DialogCloseError): void | Promise<void> | PromiseLike<void>;
4345
}

test/unit/dialog-controller.spec.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import {DefaultDialogSettings} from '../../src/dialog-settings';
2-
import {Renderer} from '../../src/renderer';
3-
import {DialogController} from '../../src/dialog-controller';
4-
import {DialogCancelError} from '../../src/dialog-cancel-error';
1+
import { DialogCloseResult } from './../../src/dialog-result';
2+
import { DialogComponentCanDeactivate } from './../../src/interfaces';
3+
import { DefaultDialogSettings } from '../../src/dialog-settings';
4+
import { Renderer } from '../../src/renderer';
5+
import { DialogController } from '../../src/dialog-controller';
6+
import { DialogCancelError } from '../../src/dialog-cancel-error';
57

68
describe('DialogController', () => {
79
let resolveCallback: jasmine.Spy;
@@ -43,13 +45,14 @@ describe('DialogController', () => {
4345
});
4446

4547
describe('".releaseResources" should', () => {
48+
const expectedDeactivateArg = {} as any;
4649
beforeEach(async done => {
47-
await _success(() => dialogController.releaseResources(), done);
50+
await _success(() => dialogController.releaseResources(expectedDeactivateArg), done);
4851
done();
4952
});
5053

5154
it('call ".deactivate" on the view model', () => {
52-
expect((dialogController.controller.viewModel as any).deactivate).toHaveBeenCalled();
55+
expect((dialogController.controller.viewModel as any).deactivate).toHaveBeenCalledWith(expectedDeactivateArg);
5356
});
5457

5558
it('call ".hideDialog" on the renderer', () => {
@@ -179,6 +182,16 @@ describe('DialogController', () => {
179182
done();
180183
});
181184

185+
it('call ".canDeactivate" with the close result', async done => {
186+
const output = 'expected output';
187+
await _success(() => dialogController.close(true, output), done);
188+
const vm = dialogController.controller.viewModel as DialogComponentCanDeactivate;
189+
const expectedResult = (vm.canDeactivate as jasmine.Spy).calls.argsFor(0)[0] as DialogCloseResult;
190+
expect(expectedResult).toBeDefined();
191+
expect(expectedResult.output).toBe(output);
192+
done();
193+
});
194+
182195
it('call the "resolve" callback on "cancel" when "rejectOnCancel" is "false"', async done => {
183196
const expected = 'cancel output';
184197
dialogController.settings.rejectOnCancel = false;

0 commit comments

Comments
 (0)