I am using Swiper.js in an Angular project to create a slider. I want the slider to loop, but I am encountering the following warning:
Swiper Loop Warning: The number of slides is not enough for loop mode, it will be disabled and not function properly. You need to add more slides (or make duplicates) or lower the values of slidesPerView and slidesPerGroup parameters.
My slidesPerView
and slidesPerGroup
parameters are set to 1, and I have a total of 4 slides. Even when I duplicate the slides (doubling the number of images), this warning persists, and the loop mode does not work.
Here is my component template:
<swiper-container
class="slider-container"
loop="true"
navigation="true"
slides-per-view="1"
slides-per-group="1"
[pagination]="{ clickable: true }">
@for (projectImagePath of projectImagesPath; track projectImagePath) {
<swiper-slide class="slider">
<img [src]="projectImagePath" alt="">
</swiper-slide>
}
</swiper-container>
What I have tried:
Despite these efforts, the loop functionality is not working, and the warning still appears.
Questions:
Here is a Stackblitz Demo
Looks like a bug in swiper when we initialize via HTML, to achieve the functionality, we can initialize through swiper initialize
function instead.
export class App {
@ViewChild('swiper') swiper!: ElementRef<any>;
ngAfterViewInit() {
// swiper parameters
const swiperParams = {
slidesPerView: 1,
navigation: true,
loop: true,
pagination: { clickable: true },
};
Object.assign(this.swiper.nativeElement, swiperParams);
this.swiper.nativeElement.initialize();
}
In the HTML, make sure you set the attribute init="false"
to prevent auto initialization.
<swiper-container init="false" #swiper>
@for (projectImagePath of projectImagesPath; track projectImagePath) {
<swiper-slide>
<img [src]="projectImagePath" alt=""/>
</swiper-slide>
}
</swiper-container>
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>
@for (projectImagePath of projectImagesPath; track projectImagePath) {
<swiper-slide>
<img [src]="projectImagePath" alt=""/>
</swiper-slide>
}
</swiper-container>
`,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class App {
@ViewChild('swiper') swiper!: ElementRef<any>;
projectImagesPath = [
'https://placehold.co/600x400',
'https://placehold.co/600x400',
'https://placehold.co/600x400',
'https://placehold.co/600x400',
];
ngAfterViewInit() {
// swiper parameters
const swiperParams = {
slidesPerView: 1,
navigation: true,
loop: true,
pagination: { clickable: true },
};
Object.assign(this.swiper.nativeElement, swiperParams);
this.swiper.nativeElement.initialize();
}
}