ionic-framework: ion-slides not working in modal when ion-button is present in modal

Bug Report

Ionic version:

[x] 4.0.1

Current behavior: On second opening of modal view with ion-slides and ion-button inside of modal template ion-slides becomes unresponsive, without ion-button everything is working correctly

Expected behavior: ion-slides should work correctly everytime modal is opened and it should not depend on other components in templates like ion-button

Steps to reproduce: Use ionic source code, core->src->components->modal->test->basic and add to test ion-slides, first time when modal is opened everything is ok, second time that modal is opened it is unresponsive, if you change ion-button in test with anchor tag everything is going to be ok

Related code:

Not working

 async function createModal() {
    // initialize controller
    const modalController = document.querySelector('ion-modal-controller');
    await modalController.componentOnReady();

    // create component to open
    const element = document.createElement('div');
    element.innerHTML = `
      <ion-header>
        <ion-toolbar>
          <ion-title>Super Modal</ion-title>
        </ion-toolbar>
      </ion-header>
      <ion-content>
        <h1>Content of doom</h1>
        <div>Here's some more content</div>
        <ion-slides mode="md">
          <ion-slide>
            <div>1</div>
          </ion-slide>
          <ion-slide>
            <div>2</div>
          </ion-slide>
          <ion-slide>
            <div>3</div>
          </ion-slide>
        </ion-slides>
      <ion-button class="dismiss">Dismiss Modal</ion-button>
    </ion-content>
      `;

    // listen for close event
    const button = element.querySelector('ion-button');
    button.addEventListener('click', () => {
      modalController.dismiss();
    });

    // present the modal
    const modalElement = await modalController.create({
      component: element
    });
    return modalElement;
  }

Working

  async function createModal() {
    // initialize controller
    const modalController = document.querySelector('ion-modal-controller');
    await modalController.componentOnReady();

    // create component to open
    const element = document.createElement('div');
    element.innerHTML = `
      <ion-header>
        <ion-toolbar>
          <ion-title>Super Modal</ion-title>
        </ion-toolbar>
      </ion-header>
      <ion-content>
        <h1>Content of doom</h1>
        <div>Here's some more content</div>
        <ion-slides mode="md">
          <ion-slide>
            <div>1</div>
          </ion-slide>
          <ion-slide>
            <div>2</div>
          </ion-slide>
          <ion-slide>
            <div>3</div>
          </ion-slide>
        </ion-slides>
      <a class="dismiss">Dismiss Modal</a>
    </ion-content>
      `;

    // listen for close event
    const button = element.querySelector('a');
    button.addEventListener('click', () => {
      modalController.dismiss();
    });

    // present the modal
    const modalElement = await modalController.create({
      component: element
    });
    return modalElement;
  }

Other information:

Ionic info:

insert the output from ionic info here

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 9
  • Comments: 16 (2 by maintainers)

Most upvoted comments

Better solution, use Ionic lifecycle hook:

ionViewDidEnter() {
    this.showSlides = true;
}

It’s more clear what the code is trying to accomplish rather than arbitrary timeouts.

In my case that was a fix:

import { IonSlides } from '@ionic/angular';

@ViewChild(IonSlides, { static: true }) slides: IonSlides;

ngOnInit() {
  this.slides.update();
}

same here, showing IonSlides in a modal page result in a serious DEAD LOCK, chrome stops responding. no matter <ion-button> or <button>, the issue persistent. temperory solution is adding a settimeout to delay show IonSlides

<div *ngIf="showSlides" class="slides-container">
    <ion-slides>
      <ion-slide *ngFor="let photo of photos">
        <img data-src="{{photo.url}}" class="slide-image"/>
        <div class="title" *ngIf="photo.title">{{photo.title}}</div>
      </ion-slide>
    </ion-slides>
</div>

ngOnInit() { setTimeout(() => { this.showSlides = true; }, 0); }

@ionic/angular 4.0.2

Better solution, use Ionic lifecycle hook:

ionViewDidEnter() {
    this.showSlides = true;
}

It’s more clear what the code is trying to accomplish rather than arbitrary timeouts.

Hi, This is work for me:

import {ViewChild, AfterViewChecked} from '@angular/core';
import {IonSlides} from '@ionic/angular';
...........................................
export class ModalPage implements OnInit, AfterViewChecked {

  @ViewChild(IonSlides, { static: false }) slides: IonSlides;
............................
 ngAfterViewChecked(): void {
    this.slides.update(); // This will update slide after view checked
  }