SweetAlert2 - Start with showLoading () and close after executing a function - javascript

I need to open SweetAlert with a loading, execute a JS function "myFunc()" and close SweetAlert.
I invoke SweetAlert with a loading:
Swal.fire ({
   title: 'Wait ...',
   onBeforeOpen: () => {
     Swal.showLoading ()
   }
})
Where should I put myFunc () in the code?

My thought would be that there isn't really any reason to include your function in the SweetAlertOptions object. Since you're only using SweetAlert2 to show a loading dialog while your function executes, and not getting any user input from it, you can just treat it in a procedural manner:
Swal.fire({
title: 'Wait ...',
onBeforeOpen () {
Swal.showLoading ()
},
onAfterClose () {
Swal.hideLoading()
},
allowOutsideClick: false,
allowEscapeKey: false,
allowEnterKey: false
})
myFunc()
Swal.close()
If you're using async/await don't await the initial Swal.fire(). You don't care about the result anyway.
If myFunc() is asynchronous (which it should be in order to not lock the UI thread during loading), await it and then close, or close in the resolution of the promise
await myFunc()
Swal.close()
OR
myFunc().then(result => {
Swal.close()
})
Alternatively, you could call myFunc and Swal.close() in the OnOpen function:
Swal.fire({
...
onOpen () {
myFunc()
Swal.close()
}
...
})
Swal.fire({
...
async onOpen () {
await myFunc()
Swal.close()
},
...
})
Swal.fire({
...
onOpen () {
myFunc().then(result => {
Swal.close()
})
}
...
})

if you use the modal of steps, you can use willOpen option with arrow function
await Queue.fire({
title: titulo,
html : html,
willOpen:()=>{
operations///
}
})
},
currentProgressStep: 0,
// optional class to show fade-in backdrop animation which was disabled in Queue mixin
showClass: { backdrop: 'swal2-noanimation' },
})

Related

SweetAlert2 executing functions while showing loading showing success after done

I am trying to create a sweetAlert2 function where I want to fire a loading screen. And during the loading screen, I want to execute some functions, which can take some time. Afterward I want to display a fire success or error, depending on what the return will be. I tried several methods:
Swal.fire({
title: 'Auto close alert!',
html: 'In progress',
timerProgressBar: true,
didOpen: () => {
try {
Swal.showLoading();
call other functions..
if success show
Swal.fire({
icon: 'success',
title: 'Success...',
html: message
});
or else fire error
catch(err){
etc.
}
}
)};
Now when I execute the function it waits a few seconds (executing functions) and then it shows the success or error fire, but it doesn't show the in-progress loading dialog first. Any idea how to get this?
Fixed it by using setTimouts and promises:
//Start
Swal.fire({
title: 'In progress',
html: 'Please wait while your action is being carried out.',
timerProgressBar: true,
didOpen: () => {
//here it will open the in progress box
Swal.showLoading();
//setTimeout with 1000 or more ms is needed in order to show the inprogress box
setTimeout(async () => {
let currentRecID = currentRecord.get().id;
//load complete record
currentRec = record.load({
type: record.Type.OPPORTUNITY,
id: currentRecID,
isDynamic: true
});
const promiseVar = () =>
new Promise((resolve, reject) => {
resolve(canCreateORD(currentRec));
});
canORDbeCreated = await promiseVar();
//Automatically close popup so it continues with willClose
Swal.close();
}, 1000);
},
willClose: () => {
//Show success / error box with Swal.fire

How to stop a function from being called when the page opens

So I have this Sweetalert2 function and it works great. Except it runs as soon as the page loads which is not what I want.
What I want is when I click on an element. I want it to be executed!
Also, I noticed that if the alert runs for the first time. It doesn't run when I click it because it ran on the first time
HTML
<i class="fas fa-search navigation__search-cart--icon"></i>
JS (SweetAlert file. From here I'm exporting the function that always gets called.)
export default sweetAlert = Swal.fire({
title: "Search...",
input: "text",
inputAttributes: {
autocapitalize: "off"
},
showCancelButton: true,
confirmButtonText: "Search",
showLoaderOnConfirm: true,
preConfirm: async val => {
try {
const response = await fetch(`//api.github.com/users/${val}`);
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
} catch (err) {
Swal.showValidationMessage(`Request failed: ${err}`);
}
},
allowOutsideClick: () => !Swal.isLoading()
}).then(result => {
if (result.value) {
Swal.fire({
title: `${result.value.login}'s avatar`,
imageUrl: result.value.avatar_url
});
}
});
JS (Where the actual click happens)
import sweetAlert from "./sweetAlert";
const search = document.querySelector(
".fas.fa-search.navigation__search-cart--icon"
);
search.addEventListener("click", sweetAlert);
What should I do to stop the function from running on page load? And how can I make it run whenever I click on the element?

how to show custom confirmation alert in loop for react JS?

Problem:
I am uploading files using "react-dropzone" and showing confirmation alert using "react-confirm-alert" if image name is already exist.
i have to verify image name duplication and show confirmation in loop but it only run one time.
Need:
I have to show confirmation alert in loop.
Issues:
In this example i am using async/await to show confirmation in loop.
its showing in loop but data from replaceImageAlert() is undefined.
please suggest better place or better solution
this example is working fine with window.confirm() but i have to use custom confirmation box.
...
async replaceImageAlert(index, fileObject){
await new Promise(function (resolve, reject) {
confirmAlert({
title: 'Confirm to update old image',
message: 'Are you sure to do this.',
buttons: [
{
label: 'Yes',
onClick: () => {
resolve(true);
}
},
{
label: 'No',
onClick: () => {
resolve(false);
}
}
]
});
});
}
...
async function abc(){
for (var i =0; i < accepted.length; i++){
var chechAndRemoveDuplicate = HF.removeDuplicateImage(accepted[i], this.props.files);
if (chechAndRemoveDuplicate.duplicate){
var temp = accepted[i];
var cb = await this.replaceImageAlert(i, temp);
console.log('cb', cb);
}else {
generateFile(i, accepted[i]).then((value)=>{
this.props.setResourceFile(value.fileObject); //add file data to file aray
});
}
}
}
Your replaceImageAlert method just waits for the promise, but it doesn't do anything with the result value, and it doesn't return anything. You will want to use
replaceImageAlert(index, fileObject){
return new Promise(function (resolve, reject) {
//^^^^^^
confirmAlert({
title: 'Confirm to update old image',
message: 'Are you sure to do this.',
buttons: [
{
label: 'Yes',
onClick: () => resolve(true)
},
{
label: 'No',
onClick: () => resolve(false)
}
]
});
});
}
So that when you do const x = await replaceImageAlert(…), the x will actually be false or true.
The await keyword is meant to be used inside an async function. To solve your issue you need to declare your functions as:
function replaceImageAlert() {
return new Promise(/* ... */);
}
async function abc() {
// some code
await replaceImageAlert();
}

Prevent going back when hardware back button is pressed in Ionic 4 App

this.platform.backButton.subscribe(()=> {
const alert = await this.alertController.create({
header: 'Confirm!',
message: 'Do you want to go back!!!',
buttons: [
{
text: 'Yes',
handler: () => {
// Previous page loaded
}
}, {
text: 'No',
handler: () => {
//Page should not go back.
//This is where i want to write code,if the user clicks
No and the back button function should be disabled.
//Only when the user presses Yes,the page will go to
previous.
}
}
]
});
})
I dont know how to handle when the user presses no,i.e.Disable the back button function or event.
Finally i solved the issue.As the event emitted from the backButton is an promise.If I dont need to go back,i just reject that promise.
this.platform.backButton.subscribe(()=> {
const alert = await this.alertController.create({
header: 'Confirm!',
message: 'Do you want to go back!!!',
buttons: [
{
text: 'Yes',
handler: () => {
// Previous page loaded
}
}, {
text: 'No',
handler: () => {
reject()
}
}
]
});
})
Try this way to prevent the back button
this.platform.backButton.subscribeWithPriority(9999, () => {
this.dismiss();
});

Jasmine unit testing, how do I trigger the click event of ngx-modal-dialog

I am working on an angular application and i am Unit testing the application using Jasmine.
The application uses ngx-modal-dialog(enter link description here) plugin for Pop-up Dialog Box such as a a confirmation box as a dynamic component.
What i want is to trigger the click event for the confirm or cancel, whatever the user chooses.
The code for the Pop-up Dialog box is as below:
export class SomeComponent {
constructor(private modalService: ModalDialogService) {}
cancleEditConfirmDialog() {
this.modalService.openDialog(this.viewRef, {
title: 'Discard Changes ',
childComponent: SimpleModalComponent,
data: {
text: 'Changes will not be saved. Do you want to proceed?'
},
settings: {
closeButtonClass: 'close theme-icon-close'
},
actionButtons: [
{
text: 'Discard',
buttonClass: 'btn btn-success',
onAction: () => new Promise((resolve: any) => {
// invoke delete
// do something such as discard changes
resolve()
})
},
{
text: 'Cancel',
buttonClass: 'btn btn-danger',
onAction: () => new Promise((resolve: any) => {
// cancel and close popup
setTimeout(() => {
resolve();
}, 20);
})
}
]
});
}
}
how do i trigger the onAction: => () in the click event for discard button
and for cancel button.
There is a problem, with testing this modal dialog, if the viewRef passed into the modalService is the actual component under test itself. This is because the modal dialog gets added into the dom outside the viewRef. So you could only access the elements inside the test using document.getElementById which would be possible, but you wouldn't have the chance to use all those nice debugElement features and so on.
There is a way though: if it's not a problem to use a div inside the component as the viewRef than the test could be done.
stackblitz
This means your template would need to look like this:
template
<div #parentDialog>
<button type="button" (click)="cancleEditConfirmDialog()">Open Dialog</button>
</div>
If thats the case the component would look like this:
component.ts
#ViewChild('parentDialog', {read: ViewContainerRef}) parentVCR;
constructor(private modalService: ModalDialogService) {}
cancleEditConfirmDialog() {
this.modalService.openDialog(this.parentVCR, {
title: 'Discard Changes ',
childComponent: SimpleModalComponent,
data: {
text: 'Changes will not be saved. Do you want to proceed?'
},
settings: {
closeButtonClass: 'close theme-icon-close'
},
actionButtons: [
{
text: 'Discard',
buttonClass: 'btn btn-success',
onAction: () => new Promise((resolve: any) => {
// invoke delete
// do something such as discard changes
resolve()
})
},
{
text: 'Cancel',
buttonClass: 'btn btn-danger',
onAction: () => new Promise((resolve: any) => {
// cancel and close popup
setTimeout(() => {
resolve();
}, 20);
})
}
]});
}
And finally your test case:
test
describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let component: AppComponent;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ModalDialogModule.forRoot()],
declarations: [ AppComponent],
schemas: [NO_ERRORS_SCHEMA]
});
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('open dialog and cancel', fakeAsync(() => {
let buttonDebugElems: DebugElement[] = fixture.debugElement.queryAll(By.css('button'));
expect(buttonDebugElems.length).toEqual(1);
expect(buttonDebugElems[0].nativeElement.innerText).toEqual('Open Dialog');
// Open
buttonDebugElems[0].triggerEventHandler('click', null);
fixture.detectChanges();
buttonDebugElems = fixture.debugElement.queryAll(By.css('button'));
expect(buttonDebugElems.length).toEqual(3);
expect(buttonDebugElems[1].nativeElement.innerText).toEqual('Discard');
expect(buttonDebugElems[2].nativeElement.innerText).toEqual('Cancel');
// cancel
buttonDebugElems[2].triggerEventHandler('click', null);
// needed to wait for the promise to resolve (20 needed due to the timeout of the cancel promise)
tick(20);
buttonDebugElems = fixture.debugElement.queryAll(By.css('button'));
expect(buttonDebugElems.length).toEqual(1);
// todo expect the things the action changed inside you component.
}));
it('open dialog and discard', fakeAsync(() => {
let buttonDebugElems: DebugElement[] = fixture.debugElement.queryAll(By.css('button'));
expect(buttonDebugElems.length).toEqual(1);
expect(buttonDebugElems[0].nativeElement.innerText).toEqual('Open Dialog');
// open
buttonDebugElems[0].triggerEventHandler('click', null);
fixture.detectChanges();
buttonDebugElems = fixture.debugElement.queryAll(By.css('button'));
expect(buttonDebugElems.length).toEqual(3);
expect(buttonDebugElems[1].nativeElement.innerText).toEqual('Discard');
expect(buttonDebugElems[2].nativeElement.innerText).toEqual('Cancel');
// discard
buttonDebugElems[1].triggerEventHandler('click', null);
// needed to wait for the promise to resolve
tick();
buttonDebugElems = fixture.debugElement.queryAll(By.css('button'));
expect(buttonDebugElems.length).toEqual(1);
// todo expect the things the action changed inside you component.
}));
});

Categories

Resources