How to close modal/Alert on back button in ionic4 (PWA)

Hi,
I am new to Ionic 4, I have managed to implement a PWA using ionic 4 with Angular.
I am having a hard time figuring out how to close modals/Alerts/ActionSheets on back-button on browser (Desktop & mobile) when served as a PWA. When I press back when a modal is open, the modal stays open and background page is navigated back.
I have tried workarounds from different forums and posts like

  1. this.platform.backButton.subscribeWithPriority(0, async () => {…

  2. fromEvent(document, ‘backButton’).subscribe(() => {…

but none of then are working for me, please can anyone help me with this, need to go production ASAP.

Currently using : ionic : 4.6.2 Angular: 7.2.2

A modal can be dismissed by calling the dismiss method on the modal controller and optionally passing any data from the modal.

Thank you for the response.
but I wanted to know, how we can trigger dismiss method on hardware back button on device and on desktop browser back navigation button is pressed.

@aaronksaunders answer is useless. Have you even read his question ?

@akshay_kanchan, did you find a solution to this issue ? I’m running into the same issue as you do.

I’m looking for a proper way to have physical backbutton and back on the browser closes modals. Can’t find a solution that fully works. Does somebody has a solution ?

Thanks

Arnaud

@connois your response to me obviously misreading the question is a bit rude and over the top. I have been supporting this community for years, so please forgive me if I make a mistake here or there no one is perfect, but that doesn’t meant you cannot be professional

1 Like

@connois, Sorry for delayed response but I did get it worked with following code in app.component’s constructor and creating a service as shown below.

app.component

    // close all popovers on back navigation, if open.
    this.router.events.subscribe((event: any): void => {
      if (event instanceof NavigationStart) {
        if (event.navigationTrigger === 'popstate') {
          this.autocloseOverlaysService.trigger();
        }
      }
    });

AutocloseOverlaysService

import { Injectable, ViewChildren, QueryList } from '@angular/core';
import { IonRouterOutlet, ActionSheetController, PopoverController, ModalController, MenuController, ToastController } from '@ionic/angular';
import { Router } from '@angular/router';

@Injectable({
  providedIn: 'root'
})
export class AutocloseOverlaysService {
  @ViewChildren(IonRouterOutlet) routerOutlets: QueryList<IonRouterOutlet>;
  lastTimeBackPress = 0;
  timePeriodToExit = 2000;

  constructor(
    private actionSheetCtrl: ActionSheetController,
    private popoverCtrl: PopoverController,
    private modalCtrl: ModalController,
    private menu: MenuController,
    private router: Router,
    private toastController: ToastController
  ) { }
  async trigger() {
    console.log('backbutton triggered');
    // close action sheet
    try {
      const element = await this.actionSheetCtrl.getTop();
      if (element) {
        element.dismiss();
        return;
      }
    } catch (error) {
    }

    // close popover
    try {
      const element = await this.popoverCtrl.getTop();
      if (element) {
        element.dismiss();
        return;
      }
    } catch (error) {
    }

    // close modal
    try {
      const element = await this.modalCtrl.getTop();
      if (element) {
        element.dismiss();
        return;
      }
    } catch (error) {
      console.log(error);

    }

    // close side menua
    try {
      const element = await this.menu.getOpen();
      if (element !== null) {
        this.menu.close();
        return;
      }
    } catch (error) {
    }
  }
}

Looks promising ! Gonna test and will send my feedback.

You are right. Words came out rude when I didn’t meant them like this. English is not my native language and sometime words come out wrong. Forgive me. WiIl be more careful.

Works good, however, it will still navigate back in addition to closing the modal, in my case i would only want it to close the modal, is there a way to stop it from navigating within the router.events.subscribe perhaps?

If anyone needs to solve this in the future,
I had to make some modifications to @akshay_kanchan solution to make it work how I wanted it:

when opening a modal, or in ngOnInit on the modals:

     if (!window.history.state.modal) {
        const modalState = { modal: true };
        history.pushState(modalState, null);
      }

then in app.component:

  @HostListener('window:popstate', ['$event'])
  onPopState() {
    this.autocloseOverlaysService.trigger();
  }

Now it will only close the modal, and not trigger a route change in angular. And multiple opening of modals (and closing with a button) only leaves one state in the history.