Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle 'Possibly unhandled rejection: backdrop click' in a general way

I have an angular service for handling modals:

angular.module('myApp').service('ModalService', function($uibModal) {
  function open(options) {
    return $uibModal.open(options);
  }
});

Now I upgraded to angular 1.6 and got this error:

Possibly unhandled rejection: backdrop click

whenever I open a modal and click somewhere else (the backdrop) and the modal closes (as intended). So I want to handle this unhandled exception in my ModalService as I do not want to handle this case everytime I use the ModalService. It is always ok to close the modal via backdrop click, this is no exception.

I tried:

angular.module('myApp').service('ModalService', function($uibModal) {
  function open(options) {
    var modalInstance = $uibModal.open(options);
    modalInstance.result.catch(function error(error) {
      if(error === "backdrop click") {
        // do nothing
      } else {
        throw error;
      }
    })
    return modalInstance;
  }
});

But this leads to the problem that I cannot handle other errors than backdrop click as they are always thrown:

ModalService.open({...}).result.catch(function(error) {
  // this will catch the error too, but the throw in the ModalService
  // will occure in parallel and will not be catched by this function
});

And if I try it like this:

angular.module('myApp').service('ModalService', function($uibModal) {
  function open(options) {
    var modalInstance = $uibModal.open(options);
    modalInstance.result.then(function(whatever) {
      return whatever;
    }, function rejection(error) {
      return error;
    });
    return modalInstance;
  });
});

it resolves the 'unhandled rejection' error, but for every case not just for 'backdrop clicked'.

Has anybody a good solution for this case?

like image 862
Andi Avatar asked Feb 23 '17 13:02

Andi


4 Answers

Unfortunately that's how they handle it in The official Plucker for Modal (ui.bootstrap.modal).

If you click on any button it logs something like this:

Modal dismissed at: Thu Feb 23 2017 21:54:26 GMT-0300 (Pacific SA Daylight Time)

What they do is:

modalInstance.result.then(function (selectedItem) {   $ctrl.selected = selectedItem; }, function () {   $log.info('Modal dismissed at: ' + new Date()); }); 

If you remove the error callback, guess what you get:

Possibly unhandled rejection: backdrop click

And even on cancel

Possibly unhandled rejection: cancel

So far, you either do that or use this workaround to silence unhandled rejections

app.config(['$qProvider', function ($qProvider) {             $qProvider.errorOnUnhandledRejections(false);         }]); 
like image 95
Veglos Avatar answered Sep 21 '22 09:09

Veglos


use this

 $uibModal.open({                     ////your code...... }).result.then(function(){}, function(res){}) 

now it will not give you error

like image 20
jitendra varshney Avatar answered Sep 20 '22 09:09

jitendra varshney


UI Specification dependent.

This is NOT the greatest workaround if there are UI specifications that the end-user must be able to click OUTSIDE the modal to close the modal.

If that is NOT the case and there is a little 'x' on the top right of the modal and/or there is a close

backdrop: false, // <<< !!!!!!! (see code below)
will prevent the end-user from clicking OUTSIDE the modal to close the modal.

$scope.change = function (changeableData, p_Mode) {
    var modalInstance = $uibModal.open({
        templateUrl: whatever,
        controller: ModalInstanceCtrl,
        scope: $scope,
        backdrop: false,  // <<< !!!!!!!
        resolve: {
            // whatever
        }
    });  

This will prevent the error "Possibly unhandled rejection: backdrop click" from occurring.

Once again, you need to look at the UI specifications and/or get permission from the analysts to implement this.

like image 45
gBerger101 Avatar answered Sep 19 '22 09:09

gBerger101


If you're using a controller within your modal. I used this on the closing event. Because 'Closing' is valid but 'Dismissing' is a rejection. This goes within your modal controller, not the parent.

            $scope.$on('modal.closing', (event, reason, closed) => {
                if (!closed) {
                    event.preventDefault();
                    $scope.$close("Closing");   
                }

            });

So your backdrop click will fire the closing event but closed will be passed false. If that's the case, prevent the default behaviour, and programmatically close the modal instead of dismiss. Bare in mind this will break use of dismiss, if you want to use it for its original purpose.

like image 37
Malcor Avatar answered Sep 21 '22 09:09

Malcor