How to create an Ionic 5 popover.

I found a few examples of setting up a popover in an Ionic 5 app; but most seemed to be missing some small piece. After getting it to work I thought I would post my recipe.

Also, for this example, I want to pass information (an ID value) to the popover and use it to determine information to be used in the popover.

Page versus Component

Technically there is no such thing as a "page" in Ionic; this is just a component with a route to it. With the ionic cli you are able to generate either a page or component; but since a popover doesn't require a route; let's go with generating a component.

ionic g component popovers/mypop

Build the popover

Then modify my mypop.component.ts:

import { Component } from '@angular/core';
import { PopoverController } from "@ionic/angular";

@Component({
selector: 'app-mypop',
templateUrl: './mypop.component.html'
})
export class MypopComponent {

persoon: any;

constructor (
private popover: PopoverController
) { }

ClosePopover() {
this.popover.dismiss();
}
}

and replace the mypop.component.html with the following:

<!-- Person Summary Popover -->
<ion-card class="person-modal">
<ion-card-content >
<h3 >{{person.name}}</h3>
<div class="user-info">
<p class="item-description">
<ion-text [innerHTML]="person.summary"></ion-text>
</p>
</div>
</ion-card-content>
</ion-card>

Declare in app

I also need to declare this component in my app. I would have thought, since I am only using this popover on one page, that I could declare this on the module for that page; but that doesn't seem to work. So, in my app.module.ts I added:

import { MypopComponent} from "./popovers/mypop/mypop.component";

@NgModule({
declarations: [MypopComponent],
entryComponents: [MypopComponent],

NOTE: you likely have other declarations or entryComponents already; so these will just be added to those.

Use the popover

All that is left is to use the popover.

In your mypage.page.ts file for your page add the following:

import { PopoverController } from '@ionic/angular';
import { PersoonComponent } from "../popovers/persoon/persoon.component";

and in your class definition add this function:

async CreatePopover(ev: any, i: number) {
const pop = await this.popover.create({
component: MypopComponent,
cssClass: 'my-custom-class',
event: ev,
translucent: true,
componentProps: {
"person": this.persons[i],
}
});
return await pop.present();
}

and in your mypage.page.html, use it like this:

<ion-grid padding>
<ion-row wrap *ngIf="personCount > 0" >
<ion-col size="3" *ngFor="let x of persons"; let i = index">
<ion-card (click)="CreatePopover($event, i)">
<app-image-shell class="user-image" animation="spinner" [src]="'data:image/jpeg;base64,' + persons[i]['image']">
<app-aspect-ratio [ratio]="{w:1, h:1}"></app-aspect-ratio>
</app-image-shell>
</ion-card>
</ion-col>
</ion-row>
</ion-grid>

The image with the popover link then passes the value of i back to the CreatePopover() function and used to load the data that will be used in the popover.

Tags: