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

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?

Using Slides Instead of Slide

@Cambodia - don’t really see how your comment should help anyone. Maybe you could elaborate your answer a bit? :yum:

@sibrannstrom - have you found a solution to your problem? I am creating IonSlide elements too with an *ngFor and then pushing onto the array and then I update the slider with the update method. when calling getActiveIndex afterwards in some cases it returns the correct index, in other ones it doesn’t return anything. Has anyone faced a similar issue?

edit: i set up the slider as child component in a page. when I first load the page, it works fine but after navigating back into this page from my overview page for the second time, it does not return anything anymore for the getActiveIndex method. Do I need to reset the ViewChild (if it’s even possible)?

HTML

<ion-slides pager="true" #slider (ionSlideWillChange) ="MethodHere()">
      <ion-slide>
        <h1>Slide 1</h1>
      </ion-slide>
      <ion-slide>
        <h1>Slide 2</h1>
      </ion-slide>
      <ion-slide>
        <h1>Slide 3</h1>
      </ion-slide>
    </ion-slides>

file.ts

@ViewChild('slider', { static: true }) slidefromHtml: IonSlides; /// use  **IonSlides** instead of IonSlide

MethodHere() {
    slides.getActiveIndex().then(id => {
         consol.log('your index', id)
      }
    });
  }

Hope can help thanks.