Search code examples
javascriptangulartypescriptangular5angular-services

how to Auto Increment Image slider In Angular


I am trying to Auto change Images in my Application which is coming from Array imgslider[] ,

I am putting the MY component FILE below

import { Component, OnInit, Input } from '@angular/core';
import {HeadService} from '../service/head.service';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
head_slider: any = [];
imgslider: any = [];

  constructor( public _HeadService: HeadService ) {  }

  slides  = [  ];

slideConfig  = {'slidesToShow': 3, 'slidesToScroll': 4};

  ngOnInit() {

  this._HeadService.getDataa().subscribe(data => {
    this.head_slider = data['articles'];
   console.log(this.head_slider);
        for (let i = 0; i < data['articles'].length; i++) {

            this.slides.push({img: data['articles'][i].urlToImage});
        }
  });
}

In the above Image slider I am using ngx-slick Image slider plugin , Here slides changes on button click , I want to auto Increment the slider Image.

I am putting html file below

<ngx-slick class="carousel" #slickModal="slick-modal" [config]="slideConfig" (afterChange)="afterChange($event)">
        <div ngxSlickItem *ngFor="let slide of slides" class="slide">
              <img src="{{ slide.img }}" alt="" width="100%">
        </div>
    </ngx-slick>

    <button (click)="addSlide()">Add</button>
    <button (click)="removeSlide()">Remove</button>
    <button (click)="slickModal.slickGoTo(2)">slickGoto 2</button>
    <button (click)="slickModal.unslick()">unslick</button>

Solution

  • If you want to automatically cycle the images you can for example use a timer Observable that emits numbers in a specified time interval.

    First add a name to the slick component in the template so you can get it also in the code. The template then looks like this:

    <ngx-slick #slickComponent class="carousel" #slickModal="slick-modal" [config]="slideConfig" (afterChange)="afterChange($event)">
        <div ngxSlickItem *ngFor="let slide of slides" class="slide">
              <img src="{{ slide.img }}" alt="" width="100%">
        </div>
    </ngx-slick>
    

    Then you can get the component as ViewChild in your header component and call the slickGoTo method of the component in a subscription to the timer observable. Here is a sample how the header component would look like with this logic added.

    import { Component, OnInit, Input, AfterViewInit, OnDestroy } from '@angular/core';
    import { timer, Subscription } from 'rxjs';
    import {HeadService} from '../service/head.service';
    import { SlickComponent } from 'ngx-slick';
    
    @Component({
      selector: 'app-header',
      templateUrl: './header.component.html',
      styleUrls: ['./header.component.css']
    })
    export class HeaderComponent implements OnInit, OnDestroy, AfterViewInit {
    head_slider: any = [];
    imgslider: any = [];
    @ViewChild('slickComponent') slickComponent: SlickComponent;
    private timerSubscription: Subscription;
    
      constructor( public _HeadService: HeadService ) {  }
    
      slides  = [  ];
    
    slideConfig  = {'slidesToShow': 3, 'slidesToScroll': 4};
    
      ngOnInit() {
    
      this._HeadService.getDataa().subscribe(data => {
        this.head_slider = data['articles'];
       console.log(this.head_slider);
            for (let i = 0; i < data['articles'].length; i++) {
    
                this.slides.push({img: data['articles'][i].urlToImage});
            }
      });
    
      public ngAfterViewInit() : void {
        this.timerSubscription = timer(1000, 1000).subscribe((nextNumber) => {
          this.slickComponent.slickGoTo(nextNumber % this.slides.length);
        });
      }
    
      public ngOnDestroy(): void {
        this.timerSubscription.unsubscribe();
      }
    }
    

    The timer must be started in the ngAfterViewInit method because before the component is not available. The first timer parameter specifies after how much time it starts and the second the interval for each next number generated. Because the timer observable generates increasing numbers all the time I use the Modulus (Division Remainder) operator to get only numbers that are valid indexes.

    To properly free and stop the timer an unsubscribe call in ngOnDestroy is needed so it does not continue to run after the component gets destroyed. You can read more about properly disposing Observables in the documentation of rxjs.