Skip to content

Commit

Permalink
feat(SwalComponent): allow user to pass native hooks as well (fixes #159
Browse files Browse the repository at this point in the history
)
  • Loading branch information
toverux committed Apr 10, 2020
1 parent 98659a9 commit 72699d3
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 21 deletions.
73 changes: 68 additions & 5 deletions projects/ngx-sweetalert2/src/lib/swal.component.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import { SimpleChange } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import OriginalSwal from 'sweetalert2';
import { dismissOnDestroyToken, fireOnInitToken, swalProviderToken } from './di';

import { SwalComponent } from './swal.component';
import { SweetAlert2LoaderService } from './sweetalert2-loader.service';

describe('NgxSweetalert2Component', () => {
/* tslint:disable:no-lifecycle-call max-classes-per-file */

describe('SwalComponent', () => {
let swal: typeof OriginalSwal;
let component: SwalComponent;
let fixture: ComponentFixture<SwalComponent>;
const testTitle = 'Test title';
const testText = 'Test text';

beforeEach(async(() => {
swal = jasmine.createSpyObj<typeof OriginalSwal>(['fire']);

TestBed.configureTestingModule({
providers: [
SweetAlert2LoaderService,
{ provide: swalProviderToken, useValue: () => import('sweetalert2') },
{ provide: swalProviderToken, useValue: swal },
{ provide: fireOnInitToken, useValue: false },
{ provide: dismissOnDestroyToken, useValue: true }
],
Expand All @@ -28,7 +36,62 @@ describe('NgxSweetalert2Component', () => {
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
it('should not print anything into the DOM', () => {
expect(fixture.nativeElement.innerHTML).toBe('');
});

it('should not have default options', () => {
const optionsKeys = Object.keys(component.swalOptions);

expect(optionsKeys.length).toBe(0);
});

it('should convert @Inputs to swal options', () => {
component.title = testTitle;
component.ngOnChanges({ title: new SimpleChange(null, testTitle, true) });

component.text = testText;
component.ngOnChanges({ text: new SimpleChange(null, testText, true) });

const { title, text, ...rest } = component.swalOptions;

expect(title).toBe(testTitle);
expect(text).toBe(testText);

expect(Object.keys(rest).length).toBe(0);
});

it('should merge options set via swalOptions with the current ones', () => {
component.title = testTitle;
component.text = testText;
component.ngOnChanges({
title: new SimpleChange(null, testTitle, true),
text: new SimpleChange(null, testText, true)
});

component.swalOptions = { title: `# ${testTitle}`, icon: 'question' };

const { title, text, icon } = component.swalOptions;

expect(title).toBe(`# ${testTitle}`);
expect(text).toBe(testText);
expect(icon).toBe('question');
});

it('should not copy special properties to the swal options object', () => {
component.swalFireOnInit = false;
component.swalDismissOnDestroy = false;
component.swalVisible = false;

component.ngOnChanges({
swalFireOnInit: new SimpleChange(null, false, true),
swalDismissOnDestroy: new SimpleChange(null, false, true),
swalVisible: new SimpleChange(null, false, true)
});

const optionsKeys = Object.keys(component.swalOptions);

expect(optionsKeys.filter(key => key.startsWith('swal')).length).toBe(0);
});
});

39 changes: 24 additions & 15 deletions projects/ngx-sweetalert2/src/lib/swal.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
AfterViewInit,
ChangeDetectionStrategy, Component, EventEmitter, Inject, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges
AfterViewInit, ChangeDetectionStrategy, Component, EventEmitter, Inject, Input, OnChanges, OnDestroy, OnInit,
Output, SimpleChanges
} from '@angular/core';
import Swal, { SweetAlertOptions, SweetAlertResult } from 'sweetalert2';
import { dismissOnDestroyToken, fireOnInitToken } from './di';
Expand Down Expand Up @@ -317,32 +317,34 @@ export class SwalComponent implements OnInit, AfterViewInit, OnChanges, OnDestro
public async fire(): Promise<SweetAlertResult> {
const swal = await this.sweetAlert2Loader.swal;

const userOptions = this.swalOptions;

//=> Build the SweetAlert2 options
const options: SweetAlertOptions = {
//=> Merge with calculated options set for that specific swal
...this.swalOptions,
...userOptions,

//=> Handle modal lifecycle events
onBeforeOpen: (modalElement) => {
onBeforeOpen: composeHook(userOptions.onBeforeOpen, (modalElement) => {
this.beforeOpen.emit({ modalElement });
},
onOpen: (modalElement) => {
}),
onOpen: composeHook(userOptions.onOpen, (modalElement) => {
this.isCurrentlyShown = true;
this.open.emit({ modalElement });
},
onRender: (modalElement) => {
}),
onRender: composeHook(userOptions.onRender, (modalElement) => {
this.render.emit({ modalElement });
},
onClose: (modalElement) => {
}),
onClose: composeHook(userOptions.onClose, (modalElement) => {
this.isCurrentlyShown = false;
this.close.emit({ modalElement });
},
onAfterClose: () => {
}),
onAfterClose: composeHook(userOptions.onAfterClose, () => {
this.afterClose.emit();
},
onDestroy: () => {
}),
onDestroy: composeHook(userOptions.onDestroy, () => {
this.destroy.emit();
}
})
};

//=> Show the Swal! And wait for confirmation or dimissal.
Expand All @@ -356,6 +358,13 @@ export class SwalComponent implements OnInit, AfterViewInit, OnChanges, OnDestro
}

return result;

function composeHook<T extends (...args: any[]) => void>(
userHook: T | undefined,
libHook: T): (...args: Parameters<T>) => void {

return (...args) => (libHook(...args), userHook?.(...args));
}
}

/**
Expand Down
3 changes: 2 additions & 1 deletion tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"no-object-literal-type-assertion": false,
"member-ordering": false,
"no-unused-expression": false,
"array-type": [true, "array-simple"]
"array-type": [true, "array-simple"],
"ban-comma-operator": false
}
}

0 comments on commit 72699d3

Please sign in to comment.