ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.07k stars 13.51k forks source link

getActiveIndex() returning wrong index #7616

Closed AlGantori closed 5 years ago

AlGantori commented 8 years ago

Short description of the problem:

I setup a simple 4 images sliders, however I see several issues.

  <ion-slides [options]="mySlideOptions"  #mySlider (ionDidChange)=SlideChanged()>
  <ion-slide>
    <h1>Slide 1</h1>
    <img  src="http://arabicrescue.com/ARABIC/LETTERS.BMP/400_1/01.png" >
  </ion-slide>
  <ion-slide>
    <h1>Slide 2</h1>
    <img  src="http://arabicrescue.com/ARABIC/LETTERS.BMP/400_1/02.png" >
  </ion-slide>
  <ion-slide>
    <h1>Slide 3</h1>
    <img  src="http://arabicrescue.com/ARABIC/LETTERS.BMP/400_1/03.png" >
  </ion-slide>
    <ion-slide>
    <h1>Slide 4</h1>
    <img  src="http://arabicrescue.com/ARABIC/LETTERS.BMP/400_1/04.png" >
  </ion-slide>
</ion-slides>

1) Initially the slider is not responsive to slideNext(), slidePrevious(), slideTo() calls , until the pane containing the app in the browser is manually nudged/resized.

2) this.slider.getActiveIndex() returns wrong index (after calls to slider.slideNext(). For example, the console would display indexes of 4 and 5 which are invalid. I expect 0 thru 3, given 4 images slides :

Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.
plugin.js:32 Native: tried calling StatusBar.styleDefault, but Cordova is not available. Make sure to include cordova.js or run in a device/simulator
swiper-widget.js:992 swiper initEvents attach
about.ts:48 slide CHANGED 5
about.ts:48 slide CHANGED 2
about.ts:48 slide CHANGED 3
about.ts:48 slide CHANGED 4
about.ts:48 slide CHANGED 5
about.ts:48 slide CHANGED 2
about.ts:48 slide CHANGED 3
about.ts:48 slide CHANGED 4
about.ts:48 slide CHANGED 5
about.ts:48 slide CHANGED 0
about.ts:48 slide CHANGED 3
about.ts:48 slide CHANGED 2
about.ts:48 slide CHANGED 1
about.ts:48 slide CHANGED 0
about.ts:48 slide CHANGED 3

What behavior are you expecting?

I expect the getActiveIndex() to return valid indexes 0 thru array of objects length - 1 I expect ionDidChange to fire on displaying the first slide, it did not.

I expect the slideNext() and slidePrev() and animation if set in the option to work, however, it requires the browser to be manually resized before it starts to work.

Steps to reproduce:

  1. Press the NEXT button, you see the ionDidChange firing causing a the display of indexes 5, 2, 3, 4, ... which seems bogus
  2. Pressing the PREVIOUS button starts showing the correct slide indexes 0, 3, 2, 1, 0, ...
  // 20160808
  SlideChanged() {
    console.log("slide CHANGED", this.slider.getActiveIndex());
  }

Which Ionic Version? 1.x or 2.x ionic@beta See ionic info below

Plunker that shows an example of your issue

http://plnkr.co/edit/7oP3HOsUhlwEmcvCgZED?p=preview

I could not get plunker to work the moment I added the code to home.ts home.html worked loading the images initially. (see update in followup comment)

Run ionic info from terminal/cmd prompt: (paste output below) ionic info shows: Cordova CLI: 6.2.0 Gulp version: CLI version 3.9.1 Gulp local: Local version 3.9.1 Ionic Framework Version: 2.0.0-beta.10 Ionic CLI Version: 2.0.0-beta.32 Ionic App Lib Version: 2.0.0-beta.18 OS: Windows 7 SP1 Node Version: v4.3.0

.END.

AlGantori commented 8 years ago

Updated config.js of plunker (bumped to var ngVer = '@2.0.0-rc.3';) and now the plunker is usable. http://plnkr.co/edit/7oP3HOsUhlwEmcvCgZED?p=preview

I am not familiar with config.js Nonetheless, the plunker now exhibits the issues I am seeing with 1) initial non-responsiveness of slider, until the pane containing the app in the browser is manually nudged/resized.

2) getActiveIndex() returning bogus values on slideNext(500) calls

3) ionDidChange not firing on first rendering of slides. It looks like it fires on app loading in a second project I have but the first evaluation of this.slider.getActiveIndex(); fails with something like

browser_adapter.js:84 ORIGINAL EXCEPTION: TypeError: Cannot read property 'activeIndex' of undefined

In the second project I have set package.json as below

  "dependencies": {
    "@angular/common": "2.0.0-rc.4",
    "@angular/compiler": "2.0.0-rc.4",
    "@angular/core": "2.0.0-rc.4",
    "@angular/platform-browser": "2.0.0-rc.4",
    "@angular/platform-browser-dynamic": "2.0.0-rc.4",
    "@angular/http": "2.0.0-rc.4",
    "es6-shim": "^0.35.0",
    "ionic-angular": "2.0.0-beta.11",
    "ionic-native": "1.3.10",
    "ionicons": "3.0.0",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.10",
    "zone.js": "^0.6.12"

$ ionic info

Your system information:

Cordova CLI: 6.2.0
Gulp version:  CLI version 3.9.1
Gulp local:   Local version 3.9.1
Ionic Framework Version: 2.0.0-beta.11
Ionic CLI Version: 2.0.0-beta.32
Ionic App Lib Version: 2.0.0-beta.18
OS: Windows 7 SP1
Node Version: v4.3.0

.END.

ganySA commented 8 years ago

I have the same issue is this a known bug?

ganySA commented 8 years ago

This issue seems to relate to using "loop" option. This then inserts some additional slides.

I have 3 slides and i would like to update slides based on the current slide but with the index's changing constantly i am not sure how i can make this possible.

PhilippStein commented 7 years ago

Also having the index bug. Swiper should be updated to the version 3.4.x as, there is now a "realIndex" field. From the swiper changelog:

New swiper.realIndex property in addition to swiper.activeIndex that returns index of active slide considering loop

rgarciape commented 7 years ago

Hi All!! I´ve the same Issue, Does someone solve it? Thanks in advance!

PhilippStein commented 7 years ago

I found an ugly workaround that is sufficient for my app:

I'm setting the index of my data array as data-id of the slide. Using the loop function, this results in several slides having the same id, which is no valid HTML, but works for my app.

<ion-slides #mySlider [options]="sliderOptions">
  <ion-slide *ngFor="let foo of bars; let i = index;" data-id="{{i}}">....

This way I'm able to get the realIndex of the slide by reading it's id field:

let swiper: any = this.mySlider.getSlider();
let activeIndex = this.mySlider.getActiveIndex();
let slide = swiper.slides[activeIndex];
let realIndex = slide.id;
rgarciape commented 7 years ago

@PhilippStein Thanks a lot !! I´m going to check it. I´ll let you know if it works for my app.

PhilippStein commented 7 years ago

In Ionic 2 Final the realIndex property is exposed but not documented. See https://github.com/driftyco/ionic/blob/aadf9312687963962913a8d51b3a225eedff296e/src/components/slides/slides.ts#L795

So the following is enough now:

<ion-slides #mySlider>
  <ion-slide *ngFor="let foo of bars">....

and: let realIndex = this.mySlider.realIndex

ekhasmamedov commented 7 years ago

This issue prevents me from doing both swipe and arrow-based navigation when looping is set to true.

p595285902 commented 7 years ago

Came from #11866. jgw96 close that issue so I am posting this again here.

Thanks @jgw96 , but I believe they are different.

Their issue is having wrong activeIndex when calling slideNext(). The issue I am having is wrong slide. The activeIndex is pointing to N which is what I want but the slide is showing the item with index N-1.

Also tried realIndex that @PhilippStein is suggesting. But realIndex is not the "real one". Please check out the log below.

    slidePrevEnd() {
        console.log("sliding Prev to active index = "+this.slider.getActiveIndex());
        console.log("sliding Prev to real index = "+this.slider.realIndex);
        if (this.slider.getActiveIndex() == 0)
            this.reachStartCallback();
    }
    slideNextEnd() {
        console.log("sliding Next to active index = "+this.slider.getActiveIndex());
        console.log("sliding Next to real index = "+this.slider.realIndex);
        this.addToViewedList();
        if (this.slider.getActiveIndex() == (this.photos.length - 1))
            this.reachEndCallback();
    }

**Logs**
search for page 0  main.js:63003:9
Will-change memory consumption is too high. Budget limit is the document surface area multiplied by 3 (324093 px). Occurrences of will-change over the budget will be ignored.  localhost:8100
Array [ "5924c53c524d260d7c98b0d8", "5924c53c524d260d7c98b0d3", "5924c53c524d260d7c98b0d1", "5924c53c524d260d7c98b0d0", "5924c53c524d260d7c98b0cf" ]  main.js:63044:13
sliding Prev to active index = NaN  main.js:63014:9
sliding Prev to real index = undefined  main.js:63015:9
sliding Next to active index = 1  main.js:63020:9
sliding Next to real index = 1  main.js:63021:9
sliding Next to active index = 2  main.js:63020:9
sliding Next to real index = 2  main.js:63021:9
sliding Next to active index = 3  main.js:63020:9
sliding Next to real index = 3  main.js:63021:9
sliding Next to active index = 4  main.js:63020:9
sliding Next to real index = 4  main.js:63021:9
search for page 1  main.js:63003:9
sliding Prev to active index = 1  main.js:63014:9
sliding Prev to real index = 1  main.js:63015:9
Array [ "5924c53c524d260d7c98b0d0", "5924c53c524d260d7c98b0cf", "5924c53c524d260d7c98b0c8", "5924c53c524d260d7c98b0c5", "5924c53c524d260d7c98b0c4", "5924c53c524d260d7c98b0c1", "5924c53b524d260d7c98b09e" ]  main.js:63044:13
sliding Next to active index = 2  main.js:63020:9
sliding Next to real index = 2  main.js:63021:9
sliding Next to active index = 3  main.js:63020:9
sliding Next to real index = 3  main.js:63021:9
sliding Next to active index = 4  main.js:63020:9
sliding Next to real index = 4  main.js:63021:9
sliding Next to active index = 5  main.js:63020:9
sliding Next to real index = 5  main.js:63021:9
sliding Next to active index = 6  main.js:63020:9
sliding Next to real index = 6  main.js:63021:9
search for page 2  main.js:63003:9
sliding Prev to active index = 1  main.js:63014:9
sliding Prev to real index = 1  main.js:63015:9
Array [ "5924c53c524d260d7c98b0c1", "5924c53b524d260d7c98b09e", "5924c53b524d260d7c98b09f", "5924c53b524d260d7c98b097", "5924c53b524d260d7c98b095", "5924c53b524d260d7c98b093", "5924c53b524d260d7c98b092" ]  main.js:63044:13
sliding Next to active index = 2  main.js:63020:9
sliding Next to real index = 2  main.js:63021:9
sliding Next to active index = 3  main.js:63020:9
sliding Next to real index = 3  main.js:63021:9
sliding Next to active index = 4  main.js:63020:9
sliding Next to real index = 4  main.js:63021:9
sliding Next to active index = 5  main.js:63020:9
sliding Next to real index = 5  main.js:63021:9
sliding Next to active index = 6  main.js:63020:9
sliding Next to real index = 6  main.js:63021:9
search for page 3  main.js:63003:9
sliding Prev to active index = 1  main.js:63014:9
sliding Prev to real index = 1  main.js:63015:9
Array [ "5924c53b524d260d7c98b093", "5924c53b524d260d7c98b092", "last" ]  main.js:63044:13
sliding Next to active index = 2  main.js:63020:9
sliding Next to real index = 2  main.js:63021:9
sliding Prev to active index = 1  main.js:63014:9
sliding Prev to real index = 1  main.js:63015:9
sliding Prev to active index = 0  main.js:63014:9
sliding Prev to real index = 0  main.js:63015:9
search for page 2  main.js:63003:9
photos.length is 5  main.js:63057:13
Calling slideTo (3)  main.js:63058:13
sliding Next to active index = 3  main.js:63020:9            <---------------------
sliding Next to real index = 0  main.js:63021:9               <---------------------
after slideTo activeIndex = 3  main.js:63062:13
after slideTo id= 5924c53b524d260d7c98b093  main.js:63063:13
real index = 0  main.js:63064:13
Array [ "5924c53b524d260d7c98b09f", "5924c53b524d260d7c98b097", "5924c53b524d260d7c98b095", "5924c53b524d260d7c98b093", "5924c53b524d260d7c98b092" ]  main.js:63066:13
sliding Prev to active index = 1  main.js:63014:9            <-----------the slider is showing the item of index 2, so sliding prev is sliding to 1; but it should showing 3 and sliding prev to 2-----------
sliding Prev to real index = 1
changulpaye commented 7 years ago

I am also getting the same issue. Anyone found the solution for this issue.

trinvh commented 7 years ago

Same issue. Slider component always return 1 for getActiveIndex()

NurdinDev commented 6 years ago

hello, does someone found a solution?

felizi commented 6 years ago

Same problem here :(

felizi commented 6 years ago

Possible solution here: https://github.com/ionic-team/ionic/issues/12297

franzisk commented 6 years ago

This is by far the worst component ever, spending days with this issue, sometimes after locking the swiper my slides.getActiveIndex() return true/false, how is that possible? Is there any alternative to this component? I really need something like Tinder on my first page and I am trying to use this component, but it's terrible.

ionitron-bot[bot] commented 5 years ago

This issue has been automatically identified as an Ionic 3 issue. We recently moved Ionic 3 to its own repository. I am moving this issue to the repository for Ionic 3. Please track this issue over there.

If I've made a mistake, and if this issue is still relevant to Ionic 4, please let the Ionic Framework team know!

Thank you for using Ionic!

ionitron-bot[bot] commented 5 years ago

Issue moved to: https://github.com/ionic-team/ionic-v3/issues/122