Popovers in Ionic 4

This took me too frikkin long to figure out, so I’m guessing other people might benefit from a writeup. I wanted to migrate a simple popover with a “close” button on the popover message. With ViewController it only required one line. Here’s the cleanest way I’ve found to do this, now that ViewController is gone.

Define the popover. When you do, pass the PopoverController itself as a parameter.

constructor(private pop: PopoverController) { }

  showPopover(event: Event): Promise<void> {
    return this.pop.create({ component: PopoverPage, ev: event,
                             componentProps: {message: 'passed message', popoverController: this.pop} })
                   .then(popover => popover.present());
  }

Note: using async/await instead is fine. I use Promises because they provide more granular control, but it doesn’t matter for this example. The important point here is I am passing this.pop.

Then in PopoverPage:

message = '';
  pop: PopoverController;

  constructor(navParams: NavParams) {
    this.message = navParams.get('message');
    this.pop = navParams.get('popoverController');
  }

  close() {
    this.pop.dismiss();
  }

The “OK” button in the popover message executes the close function when clicked. That seems to work fine. I’ve run into no issues so far.

6 Likes

I don’t understand your post yet, sorry. I need the ability to close visible inside the popover message page, so clicking a CLOSE button will close the popover message.

Sample html:

<div style="white-space: pre-wrap;" padding>{{message}}</div>
<ion-button fill="clear" (click)="close()">OK</ion-button>

My bad, I understand better your post now. I was assuming that you provided the popover a all template and not “just” a msg

Clever solution, well done :slight_smile:

2 Likes

Thanks this helps me enormously. I want all my popovers dismiss themselves after 5 seconds, so I’ve added this in the constructor, using the same passed parameter instead of the old view controller.

 constructor(navParams: NavParams) {
    this.pop = navParams.get('popoverController');
      {// set it to dismiss automatically after 5000ms
        setTimeout(() => {
          this.pop.dismiss();
        }, 5000);
       };
  }

Hi,
could you just skip the usage of the componentProps and inject the PopoverController like you did before?

Within the HostComponent:

constructor(private pop: PopoverController) { }

  showPopover(event: Event): Promise<void> {
    return this.pop.create({ component: PopoverPage, ev: event,
                             componentProps: {message: 'passed message'} })
                   .then(popover => popover.present());
  }

Within the PopoverComponent:

 constructor(private popoverController: PopoverController) {
      {// set it to dismiss automatically after 5000ms
        setTimeout(() => {
          this.popoverController.dismiss();
        }, 5000);
       };
  }