Joe Johnson
Joe Johnson

Reputation: 41

Ionic 7 modal not working on second click

I am opening a modal from a tab button. It works fine the first time i click the button but after that it wont work anymore. after i click it the first time i get the following warning in the console.

A trigger element with the ID "open-modal" was not found in the DOM. The trigger element must be in the DOM when the "trigger" property is set on an overlay component.

html:

<ion-modal trigger="open-modal" > 
        <ng-template>
        <ion-header>
          <ion-toolbar>
            <ion-buttons slot="start">
              <ion-button (click)="closeModal()">Close</ion-button>
            </ion-buttons>
            <ion-title>Privacy Policy</ion-title> 
          </ion-toolbar>
        </ion-header>
        <ion-content class="ion-padding">
          <ion-item> 
          </ion-item>
        </ion-content> 
    </ng-template>
    </ion-modal>



 <ion-tabs>
        <ion-tab-bar slot="bottom">
          <ion-tab-button  >
            <ion-icon name="chatbubbles"></ion-icon>
            <ion-label>Contact Us</ion-label>
          </ion-tab-button>
          <ion-tab-button  >
            <ion-icon name="trash-bin"></ion-icon>
            <ion-label>Delete Your Account</ion-label>
          </ion-tab-button>

          <ion-tab-button id="open-modal">
            <ion-icon name="shield-half-outline"></ion-icon>
            <ion-label>Privacy Policy</ion-label>
          </ion-tab-button> 
        </ion-tab-bar>
      </ion-tabs>

ts file

import { Component, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AlertController, IonModal, LoadingController, MenuController } from '@ionic/angular';
import { Router } from '@angular/router'; 
import { AuthenticationService } from 'src/app/system/services/authentication-service/authentication.service';
 

@Component({
    selector: 'app-login',
    templateUrl: './login.page.html',
    styleUrls: ['./login.page.scss']
})
export class LoginPage implements OnInit {
    @ViewChild(IonModal) privacyPolicyModal: IonModal;

    credentials: FormGroup;
    constructor(
        public menu: MenuController,
        private fb: FormBuilder,
        private authService: AuthenticationService,
        private alertController: AlertController,
        private router: Router,
        private loadingController: LoadingController
    ) {}

    ngOnInit() {
        this.credentials = this.fb.group({
            username: ['', [Validators.required]],
            password: ['', [Validators.required]]
        });
    }

 
  ionViewWillEnter() { 
    this.menu.enable(false);
  }

  
  closeModal(): void{
    this.privacyPolicyModal.dismiss(null, 'cancel');        
  }

    async login() {
        const loading = await this.loadingController.create();
        await loading.present();

        this.authService.login(this.credentials.value).subscribe(
            async (res) => {
                await loading.dismiss();
                this.router.navigateByUrl('/tabs', { replaceUrl: true });
            },
            async (res) => {
                await loading.dismiss(); 
                const alert = await this.alertController.create({
                    header: 'Login failed',
                    message: res.error.error,
                    buttons: ['OK']
                });

                await alert.present();
            }
        );
    }
 
    get username() {
        return this.credentials.get('username');
    }

    get password() {
        return this.credentials.get('password');
    }

  ionViewDidLeave() { 
    this.menu.enable(true);
  }
}

i have tried placing the modal html in different spots (before the tabs, after the tabs etc..) but same result each time.

Upvotes: 2

Views: 1923

Answers (1)

AmirAli Saghaei
AmirAli Saghaei

Reputation: 891

ion-tabs are usually for active states, not one time actions. I'm not sure about the exact reason, but this might be why the modal couldn't find the trigger in the DOM (hence the warning).

In this case, I suggest using isOpen attribute instead of trigger and make sure you manage your states correctly. something like that:

<ion-modal [isOpen]="openModal" (didDismiss)="closeModal()"> 
        <ng-template>
        <ion-header>
          <ion-toolbar>
            <ion-buttons slot="start">
              <ion-button (click)="closeModal()">Close</ion-button>
            </ion-buttons>
            <ion-title>Privacy Policy</ion-title> 
          </ion-toolbar>
        </ion-header>
        <ion-content class="ion-padding">
          <ion-item> 
          </ion-item>
        </ion-content> 
    </ng-template>
    </ion-modal>

 <ion-tabs>
        <ion-tab-bar slot="bottom">
          <ion-tab-button >
            <ion-icon name="chatbubbles"></ion-icon>
            <ion-label>Contact Us</ion-label>
          </ion-tab-button>
          <ion-tab-button >
            <ion-icon name="trash-bin"></ion-icon>
            <ion-label>Delete Your Account</ion-label>
          </ion-tab-button>

          <ion-tab-button (click)="openModal = true">
            <ion-icon name="shield-half-outline"></ion-icon>
            <ion-label>Privacy Policy</ion-label>
          </ion-tab-button> 
        </ion-tab-bar>
      </ion-tabs>
closeModal(){
    this.openModal = false;
}

also make sure to handle css properties as well. like the class selected, which would be appended to every active tab button, thus make them look like an active button.

Upvotes: 4

Related Questions