Tengo un componente que abre un modal ejecuta alguna acción asíncrona, y me gustaría descartar el modal una vez que se resuelva la función asíncrona, es decir, fetchData .
@Component({ }) export class MyComponent implements OnInit { openModal() { const modal = await this.modalCtrl.create({ component: MyModalComponent, }); await modal.present(); } } @Component({ }) export class MyModalComponent implements OnInit { fetchData() { this.fetchData().subscribe((response) => { // do some stuff // Dismiss the modal here }) } }Primero, debe crear un servicio genérico que envuelva la funcionalidad modal y al mismo tiempo asegurarse de mantener el estado de qué modal devuelve qué datos (en caso de que abra múltiples modales uno encima del otro).
async showModal(modalPage, fullscreen: boolean, componentProps?) { let resolveFunction: (res: any) => void; const promise = new Promise<any>(resolve => { resolveFunction = resolve; }); const modal = await this.modalCtrl.create({ component: modalPage, cssClass: fullscreen ? 'full-screen-modal' : 'half-screen-modal', componentProps }); modal.onDidDismiss().then(res => { resolveFunction(res); }); await modal.present(); return promise;}
Luego haces que la página modal sea la siguiente:
import { Component, OnInit } from '@angular/core'; import { DisplayService } from 'src/app/services/display/display.service'; @Component({ selector: 'app-rating', templateUrl: './my-modal.page.html', styleUrls: ['./my-modal.page.scss'], }) export class MyModal implements OnInit { constructor(private displayService: DisplayService) {} ngOnInit() { } sendValue() { // do whatever async task you need to do here then close modal when finished this.displayService.closeModal({...returnData}); // Optionally pass return Data here if you need it in the calling page } }Finalmente, su página principal debería verse así para mostrar sus modales y actuar sobre los datos de retorno:
async openModal(){ await this.displayService.showModal(MyModal, false, null).then( res => { // wait for the modal to return data when it exits if (res.data.value1){ const payload = {rating: res.data.value1, remarks: res.data.value2}; // make API call this.displayService.showToast(`Thank you`, 'success'); }else { this.router.navigate([`failed-route-view/`]); } }); }Una forma más sencilla de hacerlo es simplemente poner en su función fetchdata() la función de descarte modal. Sigue un ejemplo:
fetchData() { this.fetchData().subscribe((response) => { // do some stuff // Dismiss the modal here this.modalController.dismiss(); 👈🏽 }) }También puede usar un condicional (si) para verificar los datos de respuesta, si ya tiene valores, verifique si hay un Modal abierto antes de descartar el Modal. ¡Buen trabajo!
export class MyModalComponent implements OnInit { fetchData() { this.fetchData().subscribe((response) => { // do some stuff this.modalCtrl.dismiss() // Dismiss the modal here }) }}