Saving Models without asking users with beforeunload

  • 1
  • Question
  • Updated 1 year ago
  • In Progress
I'm trying to save changes to a model when the user closes the page.  I don't want to give the user a message, I just want to save the models.  Here is the code that I'm using, but it seems like it's working only some of the time.  Can someone tell me what I'm doing wrong.  Thanks!

(function(skuid){
var $ = skuid.$;
$(document.body).one('pageload',function(){
         
        $(window).on('beforeunload', function () {
            saveAllModels();
        });
        
});

})(skuid);

    function saveAllModels(){

           var SalesOrderModel = skuid.model.getModel('SalesOrder');
           var savePromise = SalesOrderModel.save();
    }
Photo of Matt Edwards

Matt Edwards

  • 102 Points 100 badge 2x thumb

Posted 1 year ago

  • 1
Photo of Matt Sones

Matt Sones, Champion

  • 31,478 Points 20k badge 2x thumb
Timing is always tricky for me. You may want to try a jquery deferred promise, like so:

function saveAllModels(){
 var dfd = new $.Deferred();
// Save all the models on the page (or you can save your single model as you did above)
 $.when(skuid.model.save(skuid.model.list())).then(function(){
  dfd.resolve();
 }
 return dfd.promise();
}
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
From what I've read, this will be quite difficult to accomplish, because model.save() invokes an asynchronous XMLHttpRequest, which is not guaranteed to be initiated or complete before the page is unloaded. See this discussion on navigator.sendBeacon, which describes some hacky potential ways to trick the browser to remaining on the same page long enough for the asynchronous process to complete, none of which are recommended. 

https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon

Ideally under the hood Skuid's asynchronous transport methods (save(), load(), etc.) would be able to be configured use sendBeacon instead of normal XMLHttpRequest in the context of unloading the window --- but this is not possible right now.