How to prevent browser message "Leaving site? Changes you made may not be saved."?

Actually (mostly for @neerja one more thing: There’s something that’s gotten completely lost in this discussion…

You will note that in my original post and my bug report, I talk about TWO workflow steps.

  1. The first is NAVIGATE to external page. That step ALWAYS succeeds silently and NEVER throws the “Leave Site?” dialog. (Using Navigate is useful, but Navigate can only change the URL displayed in the container, not the container’s parent. So, if my widget if hosted in an iFrame I need to also / instead of use a second technique - Run JavaScript - that allows me to access the parent window to do the redirect/replacement).

Why is it that Navigate always works and never causes the “Leave Site?” dialog to appear? This is just a wild-ass guess, but I assume that internally, Navigate is awaiting the completion of any promises that are outstanding in the page.

The fact that Navigate does not trigger the warning and that my alternative redirect options do is what lead me to surmise that the triggering had something to do with accessing parent.window.

The thing that does cause the “Leave Page?” dialog to be triggered is redirect technique #2:

  1. If I need to redirect not just in the iFrame, but in the hosting container (that is, the browser of the user who is visiting one of my customers’ pages, upon which my widget is iFramed), I cannot use Navigate. Navigate does not enable opening a URL in a new tab (which is the same thing as “the container of my current reference container”).

So I must use Run JavaScript to execute that redirection. There are several ways to do this, but all behave the same way. Currently, I’m executing parent.window.location.replace("redirect_url"); but other similar functions all have the same behavior.

Run JavaScript does not have easy access to pending promises. So it would seem that, even if I put a pause in front of the Run JS action in my workflow, and in front of all other steps in my workflow, there are still some things are awaiting completion that I cannot easily await.

(I get that there’s a somewhat hacky solution: I’ve seen that the progress bar has a class [or perhaps id, I can’t recall] and I suppose one could run a function to make sure that element does not exist / wait until that element goes away before proceeding with the redirect.)

But that seems like a very un-bubble-like solution to the problem of delaying a workflow step until we are no longer awaiting completion of previous actions, right?

In fact, I can’t find a native Bubble way to make such a delay happen. Outside of inserting pause actions (which for whatever reason does not properly delay execution), the only thing left is to make workflow steps dependent on some prior step.

I’m pretty sure that the one that’s the hang up is “Schedule API Workflow”. While this is undocumented, it seems that Schedule API Workflow DOES return a value as the results of its step. The data type is text, but the text is always null AFAICT. Also, that null value seems to be returned immediately (that is, the return value is not just information free in itself, but also gives us no timing information).

So in the experiment of, “OK, well let’s ensure that all downstream actions are only executed when Schedule API Workflow has completed” is not something we can do. Because looking at “results of step x ‘Schedule API Workflow’” always just shows us a null value.

Here’s the example: Step 9 kicks schedules an API Workflow:

Step 10 takes its return value and puts it into a custom state:

Step 11 reports what we find to the console:

The console reports that our custom state is null. In fact, this value is printed to the console almost immediately. And, even though all of our preceding steps MUST have executed (all of them are involved in assembling the data that we are now sending to the API Workflow), we now know that it is, in fact step 9 that’s the fly in the ointment here.

Step 9 gives us a return value of null immediately and, so, all downstream workflow steps are free to continue. These steps are very lightweight and seem to complete a short time before step 9 is actually done, causing us to reach step 17 nearly instantaneously:

Here’s the page at that moment:

As you can see, we’ve already gotten to the point where the JavaScript redirect is triggered (by a Custom Event that I’ve not shown above). The blue progress bar (though it will not take long to complete) must represent our friend Step 9.

Now, in the demonstration above, we’re triggering the JavaScript redirect. Here’s the OTHER version. Let’s say that I now change my preferences such that we will execute the Navigate redirect instead (and, in fact, I’ve just done that in my backend). Here’s what happens in that case:

In this case, the JS redirect will not fire, but the Navigate redirect will. Here are those workflow steps in the separate Custom Event workflow triggered by the boolean state (step 17) of the workflow we examined above:

What I observe in that case is that, in fact, there’s a slight delay before the redirect happens. It’s clear that “Open an external website” is aware of pending processes and only proceeds once those things are complete.

So, a couple of potential Bubble enhancements that would solve my issue (and possibly the issues of others who have run into this behavior):

  1. Give “Open an external website” an option for “open in parent’s window” (this would be helpful – and not problematic in terms of popup blocking – when the current container is an iFrame).

  2. Give us a version of pause that is process-aware. Basically, a workflow action that does whatever it is that the internal code of “open in parent’s window” is doing prior to actually executing the redirect action.

After having given this a really close look, I do agree that it’s unwise to be able to override “Leave Site?” but on the flip-side, we need some sort of Bubble-native way to do that same evaluation and only trigger fancy redirection actions once safe to do so (if we desire to do them silently, which we do!).

Best Regards,
Keith

1 Like