slideTo TypeError: undefined is not an object

I’m trying to use the slideTo method, and I’m using the exact same code as in the Docs, see below but get this error. Any advice will be super helpful and highly appreciated!

TypeError: undefined is not an object (evaluating '_this.slides.slideTo')

import { ViewChild } from '@angular/core';
import { Slides } from 'ionic-angular';

class MyPage {
  @ViewChild(Slides) slides: Slides;

  goToSlide() {
    this.slides.slideTo(2, 500);
  }
}
2 Likes

How does your slides template look like?

Are you calling it before the view is initialized? Does it still give you an error if you execute the command in ngAfterViewInit() ?

Yes, would like to know when this function is being called. Probably before the view has fully rendered (thus the slides are not available)

Here’s my view:

  <ion-slides class="slides" pager="true">
    <ion-slide class="slider" *ngFor="let i of photosArray">
    </ion-slide>
  </ion-slides>

It’s loaded when the View is loaded that’s for sure, as it’s executed upon a button click. The other thing is, I’m dynamically generating my Slider. As in I’m uploading/selecting photos from photo/camera and adding them to the slider. So to begin with, there is no slider. Maybe there’s where the problem is?

@AaronSterling and @luukschoen
Thanks guys for your assistance and great ideas! You were right! The view with the Slider in it wasn’t yet loaded! Here’s the solution:

        setTimeout(() => {
          this.slides.slideTo(this.counter, 500);
        }, 500);

Just be aware that this solution may not work on other phones.

2 Likes

The only question to which "use setTimeout" is the answer is “how do I create a difficult-to-predict-or-reproduce bug?”. @AaronSterling’s answer about ngAfterViewInit() should be marked as the solution.

In general yes, but not in my specific case. I do agree that the solution isn’t very elegant, but I’m adding slides after the view is loaded, and can add one or ten slides, depending on the user, so I need this Timeout set at each location where we operate with slides, as each time the user added/removes a slide, a movement must be made. ngAfterViewInit() will not provide such functionality. but in general for set/preloaded slides, yes, that is the solution!

1 Like

If what you are saying is true, and there is no workaround that does not use setTimeout(), I would consider that a bug in the slides component. Much of the entire point of using Angular in the first place is to have robust and reliable change detection, and setTimeout() subverts that.

1 Like

Could you please elaborate a little bit about how and when you’re adding these extra slides? Because it seems relevant to me to try and find a solution without using the timeOut. As @rapropos said, it’s very error prone and seems to circumvent the way Angular/Ionic should do it’s job with change detection. If indeed there’s no way to do this differently, I think this may should be considered a bug.

Here is my code. So I need a delay for the Camera to take the photo and then load it onto an Array which contains the images (URIs). Also this method is called by a user clicking on a button, as we don’t know when and how many times the user will do it, starting from Zero photos, up to ten maximum.

  this.camera.getPicture(options).then((imageURI) => {
    this.crop.crop(imageURI, {quality: 0.2}).then((newImage) => {
      this.photosArray.push({
        id: this.counter,
        imageURI: newImage,
      });
      this.counter++;
      setTimeout(() => {
        this.slides.slideTo((this.counter - 1), 500);
      }, 50);
    });
  });

I have the same issue… :frowning:

1 Like

Although answered, and using a lifecycle will provide a handle to the Slides component, here are some observations I’d like to add / reinforce;

  • Using setTimeout, as already mentioned shouldn’t be the preferred solution in the described scenario;
  • The Slides component is initialized asynchronously, using a setTimeout doesn’t fix this fact. It also doesn’t increase the certainty of the slideTo() method to work. Try throttling the CPU (devtools) for example and observe what happens;
  • Using ngAfterViewInit and ngAfterContentInit may give you a handle to the Slides component but the slideTo method may (and most likely) still doesn’t work;
  • Things get even more complicated when combining the Slides with the *ngIf structural directive or hidden attribute;

This article provides a more detailed explanation, scroll down a bit to the “Troubleshooting the Slides component, specific the slideTo(...) method” section. To summarize its contents;

  • Ionic’s lifecycles ionViewWillEnter or ionViewDidEnter do work when the slideTo() method is called directly.
  • To make the Slides component work with *ngIf you need to call the private method _initSlides() yourself. In the article, the downside of this technique is discussed as well.
  • To make the Slides component work with the hidden attribute the _snapGrid property of the Slides component needs to be filled with the correct values. The Slides component cannot be initialized in a hidden state (wrong values are calculated).

Hopefully this summary provides some additional insights.

3 Likes

this save my day putting slideTo() in ionViewDidEnter works