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:
- Single window with a locked item.
- More windows of the same browser with a locked item in one of these and the same item only displayed in the others.
- 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.