2

I have the following situation: I'm trying to use the Swiper library to change pictures as a carousel.

I'm using Angular 16(I will soon upgrade to v18) and the latest version of Swiper, when selecting to the next picture in the list I don't get the slidechange event.

I wanted to change data in the table after changing the image in the carousel, so I needed this event.

Template:
<swiper-container [slidesPerView]="1" [centeredSlides]="true" [navigation]="true" [pagination]="{ clickable: true }" (slidechange)="onSlideChange($event)">
    <swiper-slide *ngIf="topIssue.DescriptionPhoto.Base64StringData.length> 0"> 
    <img [src]="topIssue.DescriptionPhoto.Base64StringData" /></swiper-slide>
    <swiper-slide *ngIf="topIssue.FurtherActionPhoto.Base64StringData.length> 0"> 
    <img [src]="topIssue.FurtherActionPhoto.Base64StringData" /></swiper-slide>
</swiper-container>

Component:
  onSlideChange(swiper: any) {
    console.log(swiper);
  }

AppModule:
import { register } from 'swiper/element/bundle';


export class AppModule {
  constructor() {
    registerLocaleData(localeDe);
    register();
  }
}

1 Answer 1

1

If you want to perform the listener action from TS, we can use addEventListener, with the name as swiperslidechange, I am using AbortController to remove the listener.

export class App {
  abort: AbortController = new AbortController();
  ...

  ...

  ngAfterViewInit() {
    this.swiper.nativeElement.addEventListener(
      'swiperslidechange',
      (event: any) => {
        const [swiper, progress] = event.detail;
        console.log('from TS:', event);
      }, {
        signal: this.abort.signal,
      }
    );
  }
  ...

  ...
  ngOnDestroy() {
    this.abort.abort();
  }
}

If you want to listen to DOM events, you can listen for swiperslidechange HTML event with angular event binding.

<swiper-container init="false" #swiper (swiperslidechange)="swiperslidechange($event)">
  @for (projectImagePath of projectImagesPath; track projectImagePath) {
    <swiper-slide>
      <img [src]="projectImagePath" alt=""/>
    </swiper-slide>
  }
</swiper-container>

TS:

swiperslidechange(data: any) {
  console.log('from DOM', data);
}

Full Code:

import {
  Component,
  CUSTOM_ELEMENTS_SCHEMA,
  ElementRef,
  ViewChild,
} from '@angular/core';
import { MatGridListModule } from '@angular/material/grid-list';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [MatGridListModule],
  template: `
    <swiper-container init="false" #swiper (swiperslidechange)="swiperslidechange($event)">
      @for (projectImagePath of projectImagesPath; track projectImagePath) {
        <swiper-slide>
          <img [src]="projectImagePath" alt=""/>
        </swiper-slide>
      }
    </swiper-container>
  `,
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class App {
  abort: AbortController = new AbortController();
  @ViewChild('swiper') swiper!: ElementRef<any>;
  projectImagesPath = [
    'https://placehold.co/600x400?1',
    'https://placehold.co/600x400?2',
    'https://placehold.co/600x400?3',
    'https://placehold.co/600x400?4',
  ];

  swiperslidechange(data: any) {
    console.log('from DOM', data);
  }

  ngAfterViewInit() {
    // swiper parameters
    const swiperParams = {
      slidesPerView: 1,
      navigation: true,
      loop: true,
      pagination: { clickable: true },
    };
    Object.assign(this.swiper.nativeElement, swiperParams);
    this.swiper.nativeElement.initialize();

    this.swiper.nativeElement.addEventListener(
      'swiperslidechange',
      (event: any) => {
        const [swiper, progress] = event.detail;
        console.log('from TS:', event);
      },
      {
        signal: this.abort.signal,
      }
    );
  }

  ngOnDestroy() {
    this.abort.abort();
  }
}

Stackblitz Demo

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.