Menu Home

Angular: Adding images to a Bootstrap carousel from an array

The one sentence overview

You want to display an indeterminate number of images in a Bootstrap Carousel.

Setting the scene

The demo app I have created has the following component

import { Component, OnInit } from '@angular/core';
import { IEpisodeDetail } from './episode-detail';

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})
export class DetailComponent implements OnInit {
  
  episodeDetail: IEpisodeDetail;

  ngOnInit(): void {
    this.episodeDetail = {
      id: 1,
      title: "An Exercise in Fatality",
      productionYear: "1974",
      synopsis: "A health club owner murders one of his franchisees. Lt. Columbo is on the case.",
      imageUrls: ["assets/photos/1.jpg", "assets/photos/2.jpg", "assets/photos/3.jpg" ]
    };          
  }
}

The relevant part of the component is the episodeDetail object which has a property called imageUrls. This is an array of strings which are links to photos. In the example there are three photos in the array however this number will change if the user chose a different Columbo episode.

Before adding the Carousel component, the HTML template looks like:

<div class="card">
    <h5 class="card-header">{{ episodeDetail.productionYear }}</h5>
    <div class="card-body">
        <h5 class="card-title">{{ episodeDetail.title }}</h5>
        <p class="card-text"> {{ episodeDetail.synopsis }}</p>
    </div>       
</div>

The Bootstrap Cards component has been used to present the various properties of the episode details object.

Add the Carousel

For this example I chose the Carousel with controls. Copy the HTML into your template.

Next change Carousel HTML to:

  <div id="carouselExampleControls" data-interval="false" class="carousel slide" data-ride="carousel">
    <div class="carousel-inner">
      <div class="carousel-item" 
              *ngFor="let photo of episodeDetail.imageUrls let i = index"
               [ngClass]="{'active': i == 0 }">
               <img [src]="photo" class="d-block w-50">
      </div>      
    </div>
  <!-- carousel controls omitted -->
  </div>

The required changes are shown on lines 4, 5 & 6.

The Carousel HTML contains several divs with a class of carousel-item. Only one of these are required so delete the others.

Add a *ngFor loop which will iterate through the array of imageUrls. For reasons that will be explained shortly, the code needs to keep track of which loop iteration is processing so the loop index is exposed and accessible via the variable i.

The Bootstrap Carousel requires that one of the items has to be marked as active otherwise it will not work. So a check is made during each iteration of the loop. If this is the first iteration the active class is appended to the existing class of carousel-item to. Ultimately this produces the following div elements for the demo app.

 <div class="carousel-item active"...
 <div class="carousel-item"...
 <div class="carousel-item"...

The last change is to enclose the src attribute in square brackets and assign to the iterator photo which contains the iterations url. The complete HTML template now looks like this:

  <div class="card">
  <h5 class="card-header">{{ episodeDetail.productionYear }}</h5>
  <div class="card-body">
    <h5 class="card-title">{{ episodeDetail.title }}</h5>
    <p class="card-text"> {{ episodeDetail.synopsis }}</p>
  </div>

  <div id="carouselExampleControls" data-interval="false" class="carousel slide" data-ride="carousel">
    <div class="carousel-inner">
      <div class="carousel-item" *ngFor="let photo of episodeDetail.imageUrls let i = index"
        [ngClass]="{'active': i == 0 }">
        <img [src]="photo" class="d-block w-50">
      </div>
      <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
        <span class="sr-only">Previous</span>
      </a>
      <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
        <span class="carousel-control-next-icon" aria-hidden="true"></span>
        <span class="sr-only">Next</span>
      </a>
    </div>
  </div>
  <h5 class="card-footer"></h5>

Running the application will now show the working Carousel.

GitHub

You can find the demo application on GitHub

Help

If you need help with this email me.

Acknowledgements

Thanks to this Stackoverflow answer which finally resolved this problem on one of my own projects.

Categories: Angular

oraclefrontovik

Developer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.