2

I need to send a DELETE request to unlock the item used in the page when the browser is being closed; to do so, i've used onbeforeunload (the browsers supported by specs are only Chrome and Firefox).

If i use a return on the method, it show a pop-up message and the call work fine.

But, unluckily, the specs required to avoid this pop-up message; in this case, when the browser is closed, sometimes it works and sometimes it won't.

More specifically, i've got these cases:

  1. Single window with a locked item.
  2. More windows of the same browser with a locked item in one of these and the same item only displayed in the others.
  3. One windows of a browser whit the locked item and one or more windows of the other browser with the same item displayed.

When i close the window with the locked item the call unlock it, so if i refresh one of the pages where the same item was displayed it result utilizable.

This is what happen with the current "solution":

Firefox:
- Case 1: doesn't unlock the item.
- Case 2: unlock the item.
- Case 3: doesn't unlock the item.

Chrome:
- Case 1: doesn't unlock the item.
- Case 2: unlock the item.
- Case 3: unlock the item.

The current implementation is:

$window.onbeforeunload = function(){
    MyService.delete({id: item.id});    //The service is defined on another .js
}

Other possible solution that does't worked:

1) using onunload or onclose in place of onbeforeunload

2) whit this answer https://stackoverflow.com/a/26275621/8879273 i managed to intercept the keys event, but if the window is closed with the mouse it doesn't work (also, every time i move the cursor on the item it starts a delete call)

i've tried to change the mouse trigger with

$(window).on('click', (function () {        
    window.onbeforeunload = MyService.delete({ id: item.id });
}));

and

$(window).on('mousedown', (function () {
    window.onbeforeunload = MyService.delete({ id: item.id });
}));

but it still don't work

3) using defer

$window.onbeforeunload = function (event) {
    $scope.closing();
}

$scope.closing = function(){
    var deferred = $q.defer();
    MyService.delete({ id: item.id }).then(function(response){
        deferred.resolved(response);
    }, function(error){
        deferred.resolved(error);
    });
    return deferred.promise;
}

4) take by desperation, i've writed this (don't try it: it works fine... if you want to lock the whole computer!)

$scope.unlocking = false;

$window.onbeforeunload = function(){
    MyService.delete({id: item.id}).then(function(response){
        $scope.unlocking = true;
    }, function(error){
        $scope.unlocking = true;  // it doesn't matter if is a successful response or not
    });

    // since call are async, i've thinked to put a while to wait the response

    var res = angular.copy($scope.unlocking);
    while(res){
        $timeout(function(){
            res = angular.copy($scope.unlocking);
        }, 100);
    }
}

the problem whit this code is that the response return but the while doesn' exit.

P. Vucinic
  • 65
  • 8
  • I suggest a completely different approach: use socket.io / websockets to keep a connection between client and server, and if the connection is interrupted, unlock the item. –  Nov 15 '18 at 12:08

0 Answers0