Home > Software design >  Why am I unable to open my dialog modally in javascript?
Why am I unable to open my dialog modally in javascript?

Time:12-14

I want a dialog to remain opened while some data is being fetched from the server. This is my code:

(async()=>{
    document.getElementById("dialog").showModal();
    if(condition1 is true){
        await server_call1();
    }
    if(condition2 is true){
        await server_call2();
    }
    if(condition3 is true){
        await server_call3();
    }
    document.getElementById("dialog").close();
})();

All the server_call() are independent of each other. Upon executing the code, this error keeps popping up in my console:

Uncaught (in promise) DOMException: Failed to execute 'showModal' on 'HTMLDialogElement': The element already has an 'open' attribute, and therefore cannot be opened modally.

How do I resolve this issue? Please help me.

EDIT: This is my html:

<dialog id="dialog">
  <p style="font-family: cursive;">Fetching results, please wait.. </p>
</dialog>

CodePudding user response:

I think you are trying to call the showModal() method on an element that is already open. You can check if the element is open by checking its open attribute before calling showModal(). Here is one way you can do this:

(async() => {
    const dialog = document.getElementById("dialog");
    if (!dialog.open) {
        dialog.showModal();
    }
    if (condition1 is true) {
        await server_call1();
    }
    if (condition2 is true) {
        await server_call2();
    }
    if (condition3 is true) {
        await server_call3();
    }
    dialog.close();
})();

Alternatively, you can use the hasAttribute() method to check if the open attribute is present on the element before calling showModal():

(async() => {
    const dialog = document.getElementById("dialog");
    if (!dialog.hasAttribute("open")) {
        dialog.showModal();
    }
    if (condition1 is true) {
        await server_call1();
    }
    if (condition2 is true) {
        await server_call2();
    }
    if (condition3 is true) {
        await server_call3();
    }
    dialog.close();
})();

CodePudding user response:

From the mdn docs about HTMLDialogElement.showModal()

https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement/showModal

InvalidStateError DOMException Thrown if the dialog is already open (i.e. if the open attribute is already set on the element).

Here's your code working as expected in a live snippet:

async function sleep(time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

async function server_call(){
  await sleep(500);
}

(async()=>{
  document.getElementById("dialog").showModal();    
  await server_call();
  await server_call();
  await server_call();
  document.getElementById("dialog").close();
})();
<dialog id="dialog">
  <p style="font-family: cursive;">Fetching results, please wait 2 seconds.. </p>
</dialog>

  • Related