Check if a modal is opened

Is there any way to check if a modal is currently being presented?

I tried to use NavController to get the active view, but it gives me the page and not the modal view.

// Create and present the modal somewhere in a component/page
const modal = this.modalCtrl.create(MyModalPage);
modal.present();

// Check if we are presenting a modal in AppComponent
const view = this.navCtrl.getActive();
console.log(view.component === MyModalPage); // gives false
2 Likes

Not sure, not behing my code right now, but doesn’t present provide a promise back?

 modal.present().then(() => {
    // Do stuff it's open
 });
1 Like

Yes, but that does not help if I want to check if a modal is being presented from another component or service. The modal is presented from a service, and the check is done in the app component.

1 Like

Maybe (just an idea)…

modal.present().then(() => {
   const view = this.navCtrl.getActive();
   console.log(view.component === MyModalPage); // gives => ????
});

Same thing. The active view seems to be the view behind the modal (the page where I was on before I presented the modal).

sorry then :frowning: could have a look later tonight if I’ve got something like that in my project

Simple add a service, that holds the info if a modal is open.

modal.present().then(() => {
   modalService.setActive();
});

in your other component

  modalService.isActive() // return true or false
6 Likes

I see, so there is no official API that can do that? I have a hack in place that is similar to what you suggest, but it’s not really a good solution.

1 Like

i think a service is a really good solution for that ;). because they are made to share data between components/pages

1 Like

I had a similar issue although with ionic/angular version 1, I just decided to drop the crude solution I came up with, in case someone stumbles on this post like I did when I searched online for the same solution. I was able to check if $ionicModal is opened by checking if the modal $scope variable is shown. Since it return’s undefined if it’s not showing.
Example:

$ionicModal.fromTemplateUrl("modal.html", {
	scope: $scope,
	animation: "slide-in-up"
}).then(function(modal){
	$scope.modal = modal;
	$scope.modal.show();
});

if($scope.modal._isShown){ /*_isShown returns boolean value of true if modal is showing otherwise returns undefined */
//
// do some super cool stuff here.......
}

Although, I don’t know if this is the most elegant way to achieve this but it worked for me and hope it helps someone!

1 Like

I agree that is not a good solution since there is already a navigation controller to keep track of views. That should be the service in charge.

Do you mean check if a user’s Modal is open, remotely?

Could you not just have a status set on your back-end for each user that toggles on open/Close of the modal. For instance, a ‘modal_open’ field, something like that?

If you mean checking if the current user has the modal open, @bengtler has the right idea. Just have a modal_is_open boolean that toggles in a service

For modals, popovers, loading overlays, toast etc, you can check existence by calling getTop() on the controller:

loadingCtrl.getTop().then(v => v ? loadingCtrl.dismiss() : null);

If getTop() returns a value, you can do some work on it, else return null.

3 Likes

are you sure the controller is “loadingcontroller”?

I have used as below:

this.modalCtrl.getTop().then(v => v ? this.modalCtrl.dismiss() : this.GetRootPage());

Gosh, it has just taken me AGES to find a solution for dismissing a popover on back/forward navigation. I had subscribed to router events to dismiss the popover which worked the first time navigating away from the page, but navigating back or forward again would give an error every time afterwards: “ERROR Error: Uncaught (in promise): overlay does not exist”.

I finally fixed it with this code in my popover.component.ts (taken from your suggestion - so thank you very much!):

  constructor(private popoverController: PopoverController, private router: Router) { }

  ngOnInit() {
    this.router.events.subscribe(events => {
      if (events) {
        this.popoverController.getTop().then(popover => {
          return popover ? this.popoverController.dismiss() : null;
        });
      }
    });
(other code left out)