IONIC 4 : getActiveIndex() is not working in ion-slides

Using IONIC 4 ion-slides, I am trying to get currently clicked silde index using getActiveIndex() as below which it is not working.

    <ion-slides #testSlider (ionSlideTap)="getIndex()">
       <ion-slide>....</ion-slide>
    </ion-slides>


    @ViewChild('testSlider') slider: ElementRef;  // first way
    
    getIndex() {
         this.slider.nativeElement.getActiveIndex();
    }


    @ViewChild('testSlider') slider: Slider; //second way
    
    getIndex() {
         this.slider.getActiveIndex();
    }

And the another way as below which is also not working:

    <ion-slides #testSlider (ionSlideTap)="getIndex(testSlider)">
     <ion-slide>....</ion-slide>
    </ion-slides>
    
    
    getIndex(testSlider) {
         testSlider.getActiveIndex();
    }

Can anyone please suggest me how can I get active index or currently clicked slide index in IONIC 4 ?

Hi -

You can try this -

<ion-slides (ionSlideDidChange)="slideChanged()" ></ion-slides>

In .ts file

@ViewChild('slides') slides;

slideChanged() { 
this.slides.nativeElement.getActiveIndex().then(index => {
   console.log(index);
});
}

Hope this help you!

or

getIndex(testSlider: IonSlides) {

let p1 = testSlider.getActiveIndex();

p1.then(value =&gt; console.log(value));

}

I was a little bit confused as I saw in ide that this is a promise. If I read the doc, I am not really expecting to get a promise. https://beta.ionicframework.com/docs/api/slides/#methods
The doc is imho really confusing and bad. If I compare for example to material.io, which is also not a hit (because It has only trivial examples), but it is much more better, because it works.

Best regards, anna-liebt

I think documentation has to be updated! Moreover the has the base of Swiper

Thanks
Roopesh

Thanks for your reply.

@roopeshc Here ionSlideDidChange is not catching the click (It is not calling the slideChanged() method).

@anna_liebt

How can I use IonSlides as datatype. Is there any way to import it?

It’s not IonSlides instead Slides -

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

Anybody was able to get this working in ionic 4.0.0-rc.0 ???

1 Like

Hello,

yes you import it in your ts and can use it

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

At one of the last betas, I hope I am not to wrong it was renamed.

"@ionic/angular": "4.0.0-rc.0",

Best regards, anna-liebt

1 Like

Hello,

Here ionSlideDidChange is not catching the click (It is not calling the slideChanged() method)

Maybe you should show relared code.

Best regards, anna-liebt

Hi,
I’d like to get the active index of a slider and navigate to the next slide.
I’m using this code:

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

@Component({
  selector: 'app-local-rules',
  templateUrl: './local-rules.page.html',
  styleUrls: ['./local-rules.page.scss'],
})
export class LocalRulesPage implements OnInit {

  @ViewChild('slides') slides: IonSlides;

  slideOpts = {
    effect: 'flip',
  };
  
  ..
   nextSlide() {
    const currentIndex = this.slides.getActiveIndex();
    this.slides.slideTo(2, 200);
  }
}

but I get the error:

LocalRulesPage.html:27 ERROR TypeError: Cannot read property 'getActiveIndex' of undefined

Which is the correct way to use the slider with Ionic 4?

Thank you

cld

This is how I’ve solved;

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

@Component({
  selector: 'app-local-rules',
  templateUrl: './local-rules.page.html',
  styleUrls: ['./local-rules.page.scss'],
})
export class LocalRulesPage implements OnInit {

  @ViewChild(IonSlides) slides: IonSlides;

  slideOpts = {
    effect: 'flip',
  };
  
  ..
  nextSlide($event) {
    this.slides.getActiveIndex().then(index => {
      console.log(index);
      console.log('currentIndex:', index);
	  this.slides.slideNext();
      // OR this.slides.slideTo(index + 1);
    });
  }
}

Two considerations:

  • getActiveIndex returns a Promise

  • The right definitions is @ViewChild(IonSlides) slides: IonSlides;

cld

4 Likes

For example, in case you have set allowTouchMove: false inside of the <ion-slides> options and allow navigating only with buttons (for example with <ion-fab>), try this solution:

The Markup

<ion-slides #slider [options]="this.sliderOptions" (ionSlideDidChange)="this.slideDidChange();">
...
</ion-slides>

The Code

import { Component, OnInit, ViewChild } from '@angular/core';
import { IonSlides } 					from '@ionic/angular';

export class MyPage implements OnInit {

	// Get the `<ion-slides>` node from the Markup
	@ViewChild (IonSlides) protected slider: IonSlides;

	/** @var {number} sliderIndex Reflects the current index of the `slider`, starting at the first slide (0) */
	protected sliderIndex: number = 0;

	/** @var {object} sliderOptions Contains the options for the slider */
	protected sliderOptions: object = {
		allowTouchMove: false
	};

	[...]

	constructor() {}

	[...]

	/**
	 * @protected
	 * @async
	 * @function slideDidChange
	 * @description Function to emit, when the slider has changed (navigated)
	 * @return {Promise<void>}
	 */
	protected async slideDidChange(): Promise<void> {
		this.sliderIndex = await this.slider.getActiveIndex();
		return Promise.resolve();
	}
}

Now you can adapt “old” Ionic 3 Functions to the behaviour of Ionic 4, something like this:

this.slider.isBeginning(); -> this.sliderIndex === 0
this.slider.isEnd(); -> this.sliderIndex === [insert index of your last slide here] 

In Action

<ion-fab horizontal="start" vertical="bottom">
		<ion-fab-button
			(click)="this.slideTo('prev')"
			[hidden]="this.sliderIndex === 0" // Example to hide the Button
			[disabled]="this.sliderIndex === 0"> // Example to disable the Button
                <ion-icon name="arrow-back"></ion-icon>
        </ion-fab-button>
</ion-fab>

Oh, you want to know more about the this.slideTo('prev') Function? Sure, here you go:

	/**
	 * @protected
	 * @async 
	 * @function slideTo
	 * @description Function to trigger a slide with some additional logic
	 * @param {'prev' | 'next'} direction The direction, where we should swipe to
	 * @return {Promise<void>}
	 */
	protected async slideTo(direction: 'prev' | 'next'): Promise<void> {

		const currentSlideIndex: number = await this.slider.getActiveIndex();
		
		if (direction === 'next') {

			await this.slider.slideNext();

			// Additional Logic, depending on the current slide index
			if (currentSlideIndex === 0) {

				// Maybe some Tracking here?
			} else if (currentSlideIndex === 1) {

				// Or additional markup logic here?
			} else if (currentSlideIndex === 2) {

				// Nah? Okay :(
			} else if (currentSlideIndex === 3) {

				// But here!
			}

		} else if (direction === 'prev') {

			await this.slider.slidePrev();

			if (currentSlideIndex === 1) {

				// Maybe some Tracking here?
			} else if (currentSlideIndex === 2) {

				// Or additional markup logic here?
			} else if (currentSlideIndex === 3) {

				// Nah? Okay :(
			} else if (currentSlideIndex === 4) {

				// But here!
			}
		}
		return Promise.resolve();
	}

The usage is straight forward, like:

  • this.slideTo('prev');
  • this.slideto('next');

Hope it helps someone!

Cheers
Unkn0wn0x

Here’s an update for Ionic 4 with Angular 8 that worked out for me:

image-gallery.component.html:

  <ion-slides #sliderRef pager="true">
    <ion-slide *ngFor="let item of imageGalleryObjects">
        ...
    </ion-slide>
  </ion-slides>

image-gallery.component.ts:

import { OnInit, ViewChild, ElementRef } from '@angular/core';
import { IonSlides } from '@ionic/angular';


@ViewChild('sliderRef', { static: true }) protected slides: ElementRef<IonSlides>;

 ngOnInit() {
    console.log(this.slides);
    console.log(await this.getActiveIndex());
  }

  async slidePrev(): Promise<void> {
    await this.slides.nativeElement.slidePrev();
  }

  async slideNext(): Promise<void> {
    await this.slides.nativeElement.slideNext();
  }

  async getActiveIndex(): Promise<number> {
    return this.slides.nativeElement.getActiveIndex();
  }
}

2 Likes

It works for me, but I’m using it a little differently:

 @ViewChild('mySlider') slider: IonSlides;

then in my code:

this.slider.getActiveIndex().then((val) => { ... etc...

working perfectly. tq

When i try to get index i have tried this method

in html
<ion-slides [options]="slidesOpts" #slides (ionSlideNextEnd)="slideChanged()">

in .ts

async slideChanged() {
    await this.slides.getActiveIndex().then((index)=>{
      console.log(index);
    })
  }

but there was a problem in sliding, when i slide very slowly , slide changing is not detected how can i fix this issue?

The async/await syntax replaces the .then
So you should have

const index = await this.slides.getActiveIndex();
console.log(index);

hi just my two cents, followed @Testalus (thanks mate :slight_smile: )

on ionic version "@ionic/angular": "^4.11.5"

I had to change this line:

@ViewChild('sliderRef', { static: true }) protected slides: ElementRef<IonSlides>;

to

@ViewChild('sliderRef', { static: true }) protected sliderRef: IonSlides

due to nativeElement being undefined

usage:
this.sliderRef.slideTo(1)

or perhaps this topic is different, but meh always good to give out information :smiley:

1 Like

I had to change it also like you did @rip3rs. Thanks for mentioning it :wink:

I can’t get the active index properly when using slidesPerView: 1.15 to display a bit of the next slide at the end.

Currently I have three slides created by ngFor, and using @rip3rs solution above but tweaked to:

async slideChanged() {
    const index = await this.sliderRef.getActiveIndex();
    console.log(index);
}

it displays the index as 0, 1, 1 for the three slides instead of 0, 1, 2 which it should show.

Does anyone know how to get the correct index for the third slide using slidesPerView?