I want to send a $http.get if the page gets closed. Then I stumbold upon a problem where
promises can't get resolved because if this one last method returns, the page gets destroyed.
The following does not work because onbeforeunload can't resolve promises / does not wait for them:
window.onbeforeunload = function(
$http.get('http://someth.ing/update-state?page=unloaded').then(function(){
// never called... never sent...
}
}
I know, you can use default sync HTTP Methods but the question is generally how could we sync/wait for promises to resolve here.
My idea would be something like this:
window.onbeforeunload = function(){
var ready = false;
$http.get('http://someth.ing/update-state?page=unloaded').then(function(){
ready=true;
}
// I don't see any other opportunity to sync a promise here than this:
while(!ready) angular.noop();
// big question: did $http call the server now? Can we finally return in this method to let the browser 'exit' the page?
}
RFC
The onbeforeunload event occurs when the document is about to be unloaded. This event allows you to display a message in a confirmation dialog box to inform the user whether he/she wants to stay or leave the current page. The default message that appears in the confirmation box, is different in different browsers.
The beforeunload event is fired when the window, the document and its resources are about to be unloaded. The document is still visible and the event is still cancelable at this point. This event enables a web page to trigger a confirmation dialog asking the user if they really want to leave the page.
Cancelable: The beforeunload event can be canceled by user interaction: // by https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload#Example window. addEventListener("beforeunload", function(event) { event. preventDefault(); // Cancel the event as stated by the standard.
window. onbeforeunload = null; so what you would have to do is - add a click event listener to all your buttons and links (which redirect user to a different URI) and inside that listener - set the onbeforeunload event listener to null once they are clicked (before proceeding with the normal link/button action.
You have 2 problems:
So what to do to work within these limitations? You have a few options:
Avoid asynchronous code. You can do the http fetch before you get to this point, store the results and use them synchronously inside onbeforeunload.
Use ServiceWorker to continue doing work after page has been terminated. Again, I suggest creating, registring and activating worker before you get to handling onbeforeupload. During onbeforeupload handling - you want to postMessage
to your worker, asking it to do some work for you. This option comes with 2 caveats:
ServiceWorker is not a released standard, it's still a draft, expect API changes, browser support issues and, indeed, potential scrapping of the API all together.
Worker has no direct access to your page, you have to be aware of that, what what it means. For example - no window object, no libraries loaded on your page, separate script for the worker, exchange of data via explicit messages only - to name a few.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With