Unable to remove the unbeforeload event listener

Hi Bubble Community! :slight_smile:

I’ve been struggling for a while to create a warning for my users when they have unsaved changes in their form and they try to leave the page/refresh it. However, i found a way with the help of perplexity and an article i found to integrate this, but now i can’t remove the warning at all. :frowning:

Basically, using the beforeunload event, I am trying to track any changes in the input fields compared against the entries in the database (using a do every time workflow). Technically, if there is something in the input that the user didn’t save before, it should trigger the javascript below:

const beforeUnloadHandler = (event) => {
event.preventDefault();
event.returnValue = true;
};

// Enable warning
window.addEventListener("beforeunload", beforeUnloadHandler);

This works very well, tested in the debugger, but unfortunately there is nothing i can do to remove it, even when the condition “do every time” is no longer true. I have a button that is saving all the changes in the inputs, in the database, so the do everytime is no longer true.

The code i tried to remove the warning is below:

window.removeEventListener("beforeunload", beforeUnloadHandler);

If anyone has any knowledge whatsoever how i could go around this, it would be immensely appreciated! I am dropping some screenshots below with the things i’ve implemented. Thank you in advance!


The problem is the “beforeUnloadHandler” variable isn’t available in the scope of the 2nd run JavaScript action.

You can make the object globally available by appending it to the window object.

For example

window.beforeUnloadHandler = (event) => {
  event.preventDefault();
  event.returnValue = true;
};

window.addEventListener("beforeunload", window.beforeUnloadHandler);

And then when removing it, the object will be accessible in the window object.

window.removeEventListener("beforeunload", window.beforeUnloadHandler);

Hi Tim! Thanks for the incredibly quick reply! Much appreciated.

So I’ve taken your advice and i’ve added this code for the do every time workflow.

window.beforeUnloadHandler = (event) => {
  event.preventDefault();
  event.returnValue = true;
};

window.addEventListener("beforeunload", window.beforeUnloadHandler);

and then this code for the javascript triggered by another button:

window.removeEventListener("beforeunload", window.beforeUnloadHandler);

Unfortunately it doesn’t remove the event, but i can confirm that the warning is being shown. So the first code works, the remove one doesn’t. Attached screenshot to confirm it.

Am i missing something and doing it wrong?
Thanks a lot for the help!


Hmm the only thing I can think of is if your addEventListener function is being triggered several times, there might be multiple event listeners being added.

You can try conditionally adding the event listener only when there’s not one currently attached.

1 Like

Hi Tim. You were right. That was the issue.
If i change the do every time with “do once”, the addevent gets triggered correctly and the removeevent works on the button click - which is what I wanted.

However, given that it only works with “do once”, I have to think of another way to check if the data stored is different than the data in the input. Theoretically, the do every time condition would have worked, because it would always check for that condition when it becomes true - the problem was that it was triggering it several times (or at least that’s what we assume given that do once works with removing the listener).

Can you suggest any other way to constantly verify if the data stored is different than the one in the input, and if yes, to trigger the javascript?

Thanks Tim!

You should only be adding the listener once. Your Bubble WF is running your script (which adds an event listener) everytime your “Do When” event triggers.

Add the listener once (ie run the script once) in a Page load event. Note that if you are using any “Navigate to current page” the page load event triggers too. If that’s the case use a boolean state to ensure that the Run JS action runs only once.

It would be easiest to add the conditional check in the code, and look for a value on the window object.

Something like this:

if(!window.beforeUnloadHandler){
window.beforeUnloadHandler = (event) => {
  event.preventDefault();
  event.returnValue = true;
};

window.addEventListener("beforeunload", window.beforeUnloadHandler);
}

And then

if(window.beforeUnloadHandler){
window.removeEventListener("beforeunload", window.beforeUnloadHandler);
window.beforeUnloadHandler = null;
}

This topic was automatically closed after 70 days. New replies are no longer allowed.