3

I'm looking for a way to cancel the resolve of a Angular-UI Bootstrap modal and stop it from opening. The dismissAll method is not working because the modal instance is added to the modal stack only after the resolve has completed.

I have a website where modals open and close on route change. If dismissAll is called during route change to close any old modals it won't affect modals that are still resolving. So you come to the new route but the old modal still pops up after its resolve has completed.

schneikai
  • 289
  • 1
  • 10

2 Answers2

0

As things stand right now, there is no way to cancel ES6 and $q promises. you can refer to this question for more info.

tl;dr Bluebird allows promise cancellation

If you really need it you can add bluebird to angular.

If you still want to use plain ol' $q, here's what I would have done

  1. Pass the modal the current state (if using ui-router) or route (if using angular router).
  2. When you need to render the modal template compare the current state to the provided state.
  3. If they are not equal discard the modal

The modalInstance object exposes a rendered promise that will run when the modal finished rendering, you can place $uibModalStack.dismissAll(); inside.

Example:

modalInstance.rendered.then(function (currentState) {
    if (currentState !== $state.current) {
        $uibModalStack.dismissAll();
    }
}, function () {
    $log.info('Modal dismissed at: ' + new Date());
});

Of course you can defer your loading after rendering the modal and avoid this mess altogether.

Community
  • 1
  • 1
svarog
  • 9,477
  • 4
  • 61
  • 77
  • After some more investigation I found no way to dismiss the modal while it is resolving. The earliest possible moment is inside the *opened* promise. I added application specific code to check if the modal should still open and dismiss it if not. Thank you for your answer anyway :) – schneikai Jan 12 '17 at 16:49
0

This is by far the simplest way to make sure modals never stick around, and it works for apps with simple modal use. I’ve seen this working for years at several places and reliably. Essentially, you register a state change listener in your router and whenever there’s a state change you make sure to dismiss all open modals, whatever those might be. Again, this might seem harsh, but in some apps this works like a charm, and is better than nothing.

A simple example, using UI Router’s $transition service and Angular UI Bootstrap’s $uibModalStack, this can be as simple as:

$transitions.onFinish({}, function(transition) {
  $uibModalStack.dismissAll();
});

And of course, if needed, you can only perform this for transitions that match a specific criteria.

Source: https://www.codelord.net/2017/12/11/reliably-managing-modals-in-angularjs/

Eduardo Cuomo
  • 17,828
  • 6
  • 117
  • 94