Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slides.slideTo not working when filling slides with data of promise #6703

Closed
elineopsommer opened this issue May 31, 2016 · 35 comments
Closed
Assignees
Labels
ionitron: v3 moves the issue to the ionic-v3 repository

Comments

@elineopsommer
Copy link

elineopsommer commented May 31, 2016

Short description of the problem:

After filling the slides with data of an promise, sliding to specific slide is not working.
When I click on the button, then the sliding to specific slide is working. But I want to slide the slider to an specific slide by startup of the page.
See plunker for example of issue. (home.html & home.ts)

What behavior are you expecting?

Relevant code:

  @ViewChild('mySlider') slider:Slides;
  private slides:JSON;

  constructor() {
        this.getSlidesOfApi().then((slides:JSON) => {
          this.slides = slides;
          this.slider.slideTo(3,0);
        });
    }


    private getSlidesOfApi():Promise<JSON>{
      return new Promise((fulfill, reject) => {
        let jsonSlides = [
          {title:"slide 1"},{title:"slide 2"},{title:"slide 3"},{title:"slide 4"},{title:"slide 5"}
        ];
        fulfill(jsonSlides);
      })
    }

    public slide(){
      this.slider.slideTo(3,0);
    }

Which Ionic Version? 2.x

Plunker that shows an example of your issue

http://plnkr.co/edit/LTGjnmJMTjqwX25xtFjV?p=preview

Run ionic info from terminal/cmd prompt: (paste output below)
Your system information:

Cordova CLI: 5.4.1
Gulp version: CLI version 3.9.0
Gulp local: Local version 3.9.1
Ionic Framework Version: 2.0.0-beta.7
Ionic CLI Version: 2.0.0-beta.25
Ionic App Lib Version: 2.0.0-beta.15
ios-deploy version: Not installed
ios-sim version: Not installed
OS: Mac OS X El Capitan
Node Version: v5.3.0
Xcode version: Xcode 7.3.1 Build version 7D1014

@elineopsommer
Copy link
Author

@Ionitron It is on both the platforms: android and ios

@jgw96 jgw96 added the v2 label May 31, 2016
@brandyscarney
Copy link
Member

There are console errors of Cannot read property 'slideTo' of undefined. The ViewChild is set before the ngAfterViewInit callback is called so this needs to be in the ngAfterViewInit callback. Then, there is something going on with the timing that we'll have to look into. This workaround is working for me:

ngAfterViewInit() {
  this.getSlidesOfApi().then((slides:JSON) => {
    this.slides = slides;
    setTimeout(() => {
      this.slider.slideTo(3,0);
    });
  });
}

Let me know if that helps!

@brandyscarney brandyscarney self-assigned this Jun 2, 2016
@elineopsommer
Copy link
Author

@brandyscarney It still doesn't work if you do it with an Http request.
I updated the plunk: http://plnkr.co/edit/LTGjnmJMTjqwX25xtFjV?p=preview

@elineopsommer
Copy link
Author

elineopsommer commented Jun 2, 2016

@brandyscarney if you set the timing on the settimeout on 150 then it will work in the plunker, but not when you run it on a phone. So messing with the timeout seems not a good solution.

@elineopsommer
Copy link
Author

@brandyscarney any updates on this?

@elineopsommer
Copy link
Author

@jgw96 Any updates on this? I need this..

@SkogDev
Copy link

SkogDev commented Jul 11, 2016

Any updates on this?

@elineopsommer
Copy link
Author

I still got the issue..

@brandyscarney
Copy link
Member

Can anyone please provide a plunker that reproduces the problem? The plunker attached is working for me.

@elineopsommer
Copy link
Author

@brandyscarney It is working on the plunker, but not on a phone.

@brandyscarney
Copy link
Member

@elineopsommer Ahh yeah sorry. Unfortunately I haven't had time to really look into this, but I believe it is caused by the init of the slider being wrapped in a setTimeout. There are some timing errors in slider and I believe it will require a rewrite of the component: https://github.com/driftyco/ionic/blob/master/src/components/slides/slides.ts#L396

@elineopsommer
Copy link
Author

Do you have a timeline on it?

@brandyscarney
Copy link
Member

Not currently. We've been holding off on making changes to the slider until we add a new gesture controller: #7212

Then we're going to need to evaluate the slides as a whole to resolve all the underlying issues:
#6198
#6007
#5508
#6301
#6313
#6515
#6678
#6843

@galuszkak
Copy link

galuszkak commented Jul 26, 2016

@brandyscarney I see why this is failing. Can I propose alternative implementation to initialisation of Slides?
Now we have this https://github.com/driftyco/ionic/blob/master/src/components/slides/slides.ts#L396 :

setTimeout(() => {
   var swiper = new Swiper(this.getNativeElement().children[0], options);
   this.slider = swiper;
}, 300);

So we actually make it initialise later for whatever good reason is for that.

What I propose is change that to make it observable:

class Slides{
  /**
   * private
   */
  slider$: BehaviorSubject<Swiper> = new BehaviorSubject(null);

  /**
   * public for dealing with async initialisation of Swiper;
   */
  getSlider$(): Observable<Swiper>{
    return this.slider$;
  }

  ngOnInit() {
    [...]
    Observable.of(options)
      .debounceTime(300)
      .map((options)=>new Swiper(this.getNativeElement().children[0], options))
      .subscribe((swiper)=>{
        this.slider = swiper;
        this.slider$.next(swiper);
      });
  }

}

This implementation solve CORE issue which is async initialisation of slider. It makes also easy for other developers to catch Swiper object after it's initialised.

@galuszkak
Copy link

@brandyscarney as #7212 is done will you be so kind to look on my proposal above for this issue?

@rico
Copy link

rico commented Oct 13, 2016

My turn ;-) any update on this?

I have the same problem - no problem when running in the browser, but on the phone I get ERROR: EXCEPTION: Uncaught (in promise): TypeError: undefined is not an object (evaluating 'this.slider.slideTo'). Using Ionic RC0.

@wh33ler
Copy link

wh33ler commented Nov 4, 2016

any news here? Have the same issue and no good solution for this yet.

@dallastjames
Copy link

dallastjames commented Dec 5, 2016

This may not be the best solution to this problem, but it works out pretty good for a temporary workaround and hopefully helps someone until we get a more permanent solution.

@ViewChild('weekSlider') weekSlider: Slides;

private _watchSlideLength():any {
        if(!this.weekSlider || this.weekSlider.length() < 1) {
            console.log('not ready');
            return setTimeout(() => {
                return this._watchSlideLength();
            }, 50);
        }
        else {
            console.log('ready', this.weekSlider.length());
            return setTimeout(() => {
                this.weekSlider.slideTo(2);
            }, 50);
        }
}

In my case, the data I'm loading is 5 weeks worth of data and so I want to slide to the middle of the five weeks that get loaded after the data gets loaded. I call this function after I get my data and it watches for the slider to be initialized and have a length of greater than 0 to know that the slider is ready. Once it has a length, the slideTo method should be available.

Like I mentioned above, it's not a great solution, but it's one that has been working for me (Android & iOS). Hope it helps someone! :)

@salazarr-js
Copy link

@dallastjames is there a way to implement that with an observable?

@dallastjames
Copy link

dallastjames commented Jan 21, 2017

@Slzr When I originally wrote that I couldn't find any accessible observables regarding the slider to subscribe to that would help know when the slider had loaded the slides based on the data. I know that the latest release of Ionic RC5 the slides component was refactored and rewritten and so it may have better compatibility at this point. I haven't looked at the changes much to see if there is anything new that could help refactor the above solution to use observables, but there may be. It may be worth looking at some of the new output events to see if any fire as the slides are being dynamically created.

@KleinTong
Copy link

i try to add
import { Slides } from 'ionic-angular';
and it works.
i hope it can help you.

@andmar8
Copy link

andmar8 commented Mar 13, 2017

I'm assuming this still hasn't really gone anywhere?

@aviqbaihaqy
Copy link

aviqbaihaqy commented Apr 8, 2017

it work in my code
place the slideTo in ionViewDidEnter function

ionViewDidEnter() {
   this.slides.slideTo(this.itemIndex, 500);
 }

check this. lifecycle view in ionic http://blog.ionic.io/navigating-lifecycle-events/

@PunkHaz4rd
Copy link

PunkHaz4rd commented May 22, 2017

Still an issue, and not just on iOS

@pdyraga
Copy link

pdyraga commented Jul 14, 2017

I was playing with various output events and couldn't find any firing at the appropriate moment. The workaround proposed by @dallastjames is still the best one available now.

@andmar8
Copy link

andmar8 commented Jul 14, 2017

yup, just wait until the slider length is what you would expect "then" call slider.slideTo... but there really, really, really should be some form of promise on the slider when it has updated the contained slides so you can chain a then(()=>{}).

Maybe something like slider.onSlidesChanged() ???

@BalajiR
Copy link

BalajiR commented Jul 20, 2017

For the same scenario (slides based on data from API call), i'm able to get this slideTo works only when the slide changes are watched through ViewChildren (QueryList) as below :

// Mentioned only the lines required to keep it simple
@ViewChild(Slides) slides: Slides;
@ViewChildren(Slide) slideCollection: QueryList<Slide>;

slideIndexToMove = 2;

// Ionic lifecycle
ionViewDidLoad() {

 this.slideCollection.changes.subscribe((r) => {
    setTimeout(() => {
       this.slides.slideTo(this.slideIndexToMove, 0);
    });
 });
}

@pistou
Copy link

pistou commented Mar 13, 2018

This issue is still a thing in ionic 3 👎

@andmar8
Copy link

andmar8 commented Mar 13, 2018

Yup, quite a few people complaining about really long terms bugs in ionic of late, but they have been busy with ionic 4, so....

As posted above, the only solution I found was using a wait loop to check for the length of slides you are expecting.... or just delaying the execution path once for an arbitrary period of time (say... 500ms) as some have suggested.

@himgodfreyho
Copy link

Problem still exists on latest ionic.
Was debugging over and over until I found this post.
@dallastjames solution saved my day!

@Godbluff
Copy link

Godbluff commented Sep 5, 2018

I've been grappling with this issue for a while. I have a set of sliders that are being shown and hidden by an ngIf. Without a timeout long enough the slides consistently return a length of undefined, which of course wrecks anything you're trying to in addition to showing the slides, such as moving to a specific slide. So for me the solution of waiting for the length on the slides was not working.

I did discover that i could use the (ionSlideReachStart) on the ion-slides element as a safe indicator that the slides were ready. I use this event as a staring point. In my case I have a set Timeout loop checking a boolean that is set to true by the ionSlideReachStart. Obviously there's more happening when hiding the slider etc, but for me this was a good place to start.

I realize that for anyone using this event for other functionality on the slides might run into some other issues, but hopefully someone might find this solution useful. Still a hack, so I hope a more specific envent might be available in the future.

@ap1969
Copy link

ap1969 commented Sep 19, 2018

I got it working with the solution by @baihaqyaviq - thanks so much!

Solution at #6703 (comment)

@adamdbradley adamdbradley added the ionitron: v3 moves the issue to the ionic-v3 repository label Nov 1, 2018
@ionitron-bot
Copy link

ionitron-bot bot commented Nov 1, 2018

Thanks for the issue! We have moved the source code and issues for Ionic 3 into a separate repository. I am moving this issue to the repository for Ionic 3. Please track this issue over there.

Thank you for using Ionic!

@imhoffd imhoffd added ionitron: v3 moves the issue to the ionic-v3 repository and removed ionitron: v3 moves the issue to the ionic-v3 repository labels Nov 1, 2018
@ionitron-bot
Copy link

ionitron-bot bot commented Nov 1, 2018

Thanks for the issue! We have moved the source code and issues for Ionic 3 into a separate repository. I am moving this issue to the repository for Ionic 3. Please track this issue over there.

Thank you for using Ionic!

@ionitron-bot
Copy link

ionitron-bot bot commented Nov 1, 2018

Issue moved to: ionic-team/ionic-v3#99

@ionitron-bot ionitron-bot bot closed this as completed Nov 1, 2018
@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Nov 1, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
ionitron: v3 moves the issue to the ionic-v3 repository
Projects
None yet
Development

No branches or pull requests