*ngIf inside ion-slide not quite working with loop:true

Here is a stackblitz that shows the problem: https://stackblitz.com/edit/ionic-angular-v5-srhexv. And here is a short video showing the problem manifest in my application: https://vimeo.com/442433977

My HTML looks (reduced) like this:

<ion-slides pager="true" [options]="slideOpts" class="hero-banner" style="height: 100%">
    <ion-slide>
      <div *ngIf="!myobj?.myprop">
         Hello World 1!
      </div>
    </ion-slide>
    <ion-slide>
      <div *ngIf="!myobj?.myprop">
         Hello World 2!
      </div>
    </ion-slide>
    <ion-slide>
      <div *ngIf="!myobj?.myprop">
         Hello World 3!
      </div>
    </ion-slide>
</ion-slides>

slideOpts looks like this:

  slideOpts = {
    initialSlide: 0,
    speed: 400,
    loop: true,
    autoplay: {
      delay: 5000
    },
    pagination: {
      el: '.swiper-pagination',
      type: 'bullets',
      clickable: true
    }
  };

And during that whole video, nothing is changing the state of myobj or myobj.myprop. When I click and start dragging the ion-slide, the *ngIf state on the slide I clicked on is correctly reflected.

When the page loads and the ion-slides starts auto-paging, all the *ngIfs are correct the first time through. The second time through, the first slide does not reflect the correct *ngIf state, and that continues to be the case thereafter (unless I click and drag the slide and take it out of auto paging mode).

Now, things get even more interesting. When I break out of the autoplay mode by clicking, if I swipe Slide 1 to the left, then bring it back by swiping Slide 2 to the right, Slide 1 still correctly reflects the *ngIf state. If, however, I swipe left twice so that I’m on slide 3, and then swipe left again to loop around back to Slide 1, then it’s back to reflecting the wrong *ngIf state!

Obviously something about the loop mode implementation of SwiperJS breaks Angular change detection. Is there a workaround / fix?

Aside: I just found this SO post: https://stackoverflow.com/questions/46932325/ionic-3-slides-loop-does-not-refresh-properly-when-going-from-last-to-first-or-f

For what it’s worth, I just put in a bit of a hack using injected private cdr: ChangeDetectorRef and a destroy variable *ngIf’ing the ion-slides element initialized to false.

So… whenever my state variable changes, I do this little dance:

this.destroySlides = true;
this.cdr.detectChanges();
this.destroySlides = false;
this.cdr.detectChanges();

Kinda gross, but it does the trick.

1 Like