Bootstrap Carousel does not auto-slide when routing back in angular?

The Problem is when I start my angular application the image slider using bootstrap carousel is working fine. But when I routing to the other view and coming back to the image slider view it’s not auto sliding and also I can use next and prev button to change the images but it is not auto-sliding. It works only when I reload the page. How to solve this ?

Here is my code

.html file

    <div id="myCarousel" class="carousel slide carousel-fade" data-bs-ride="carousel" data-bs-pause="false">
    
      <!-- CAROUSEL INDICATORS -->
      <div class="carousel-indicators">
        <div *ngFor="let image of images;index as i;first as isFirst" [class.active]="isFirst">
          <button type="button" data-bs-target="#myCarousel" [attr.data-bs-slide-to]="i" aria-current="true">
          </button>
        </div>
      </div>
      
      <!-- CAROUSEL IMAGES -->
      <div class="carousel-inner">
        <div class="carousel-item active" data-bs-interval="2000" *ngFor="let image of images;first as isFirst" [class.active]="isFirst">
          <img id="carouselImage" src="{{image}}" class="d-block w-100" height="707vh" alt="">
          <div class="carousel-caption d-none d-md-block">
            <h3>It Differentiates Your Brand From Others</h3>
            <p>Kajah Industrial is The leading Industrial In The Country.</p>
            <button class="btn" (click)="btnService()">Watch Our Services</button>
          </div>
        </div>
      </div>
    
      <!-- NEXT AND PREV BUTTON -->
      <button class="carousel-control-prev" type="button" data-bs-target="#myCarousel"  data-bs-slide="prev">
        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
        <span class="visually-hidden">Previous</span>
      </button>
      <button class="carousel-control-next" type="button" data-bs-target="#myCarousel"  data-bs-slide="next">
        <span class="carousel-control-next-icon" aria-hidden="true"></span>
        <span class="visually-hidden">Next</span>
      </button>
    </div>

.ts file

import { bootstrap } from 'bootstrap';
...
 ngOnInit() {
    var myCarousel = document.querySelector('#myCarousel')
    var carousel = new bootstrap.Carousel(myCarousel)
  }

angular.json file

 "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "node_modules/font-awesome/css/font-awesome.min.css",
              "./node_modules/aos/dist/aos.css",
              "src/styles.css"
            ],
 "scripts": ["./node_modules/jquery/dist/jquery.min.js",
             "./node_modules/popper.js/dist/umd/popper.min.js",
             "./node_modules/bootstrap/dist/js/bootstrap.min.js",
             "./node_modules/aos/dist/aos.js"
            ]

And also I found this error in the console

*ERROR TypeError: Cannot read property ‘Carousel’ of undefined at HomeComponent.ngOnInit *

Answer

There are a couple of things to consider. You can add declare var $: any; under the import statements in your .ts file. This will allow you to access jQuery in Angular which is used by bootstrap carousel.

You shouldn’t try and initialize the carousel in the ngOnInit method, but instead use ngAfterContentInit. ngOnInit fires before the view renders, so your query selector can’t find the component because Angular has not added it yet to the DOM.

You can read here about Angular lifecycle hooks.

ngAfterContentInit

Respond after Angular projects external content into the component’s view, or into the view that a directive is in.

ngAfterContentInit() {
  const myCarousel = document.querySelector('#myCarousel');
  const carousel = $(myCarousel).carousel();
}

Also you should use a ViewChild to reference the control instead of using document.querySelector as this Angular’s preferred way of access DOM elements.

declare var $: any;

ViewChild('carousel', { static: false }) private _carousel: ElementRef;

ngAfterContentInit() {
   const myCarousel = this._carousel.nativeElement;
   const carousel = $(myCarousel).carousel();
}

In your html add #carousel

<div #carousel id="myCarousel" class="carousel slide carousel-fade" 

Leave a Reply

Your email address will not be published. Required fields are marked *