Learn to Build an Angular Slider, Fast!

Last Updated on August 9, 2024 by E. Scott

This basic Angular slider component is malleable, responsive, and dynamic. Sometimes called a carousel too. There’s so many variations of how this can work. Use an API for the graphics and data. Add smooth transitions or image descriptions. However you decide you modify it, enjoy the feature.

If you’re new to TypeScript, the accordion is a nice component and perhaps a good beginner project. If you’re familiar with TypeScript, this project may be a better fit. This one on the other hand has over 200 forks.

Git Repo

Angular Slider Interface

The interface is a mirror of what the data looks like. They were designed to describe object shapes and check for necessary keys. They’re virtual structures that exist solely in TypeScript at run time. Not thereafter simply because JavaScript doesn’t have such a feature.

Fortunately for us, the object is rudimentary. More complex objects result in more complex interfaces. Though there are tools that convert data to interfaces, I prefer writing them myself.

We can see in the code below, there’s seven properties we need to match upon receiving the slider payload. The payload is a data source comprised of JSON. Our Angular slider relies on this payload.

export class DataInterface {
  title: string;
  author: string;
  status: boolean;
  url: string;
  link: string;
  altText: string;
  description: string;
}

Angular Slider TypeScript

There’s a variety of things happening in the TypeScript file. Let’s go over them.

  • unsubscribe is a private variable because no other class needs to know about it. We use it to end the subscription when the component life cycle is finished. This is denoted by the ngOnDestroy hook at the bottom. In ngOnInit we’re saying, subscribe to this data, or takeUntil unsubscribe is void.
  • result is our main array with the aforementioned interface reference.
  • currentIndex is our indice/ reference to the currently active book.
  • productInfo is whether the book description is shown or not.
  • Set the private _http variable.
  • GET the response and store it in the results variable.
  • changeShowcase resets all the objects’ status’ values to false. Then sets the incoming value to true.
  • next and prevBook simply retrieve the current index of the original data stream, and reset the status values. Both of which are set via currentIndex++, subtract with currentIndex–, or set it to zero if we reach the end.
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { DataInterface } from './data.interface';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})

export class AppComponent {
  private unsubscribe$ = new Subject<void>;
  result: DataInterface[] = [];
  currentIndex: number = 0;
  productInfo: boolean = false;
  loaded: boolean = false;

  constructor(private _http: HttpClient) {}

  ngOnInit() {
    this._http.get<DataInterface[]>('path-to-json')
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe((val) => {
        this.result = val;
        this.getSliderImage(this.currentIndex);
      });
  }

  ngOnDestroy(): void {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }
}

The first function below changes the showcased image via the buttons at the bottom. The function receives the index of the selected radio button. We then use that index in the result array to retrieve the url.

The next function is used on the code above. This also obtains the url. Lots of the functions here are updating the index and piping in the correct data.

  changeShowcase(i: number) {
    this.currentIndex = i;
    this.result[this.currentIndex].url;
    this.resetValues();
    this.result[i].status = true;
  }

  getSliderImage(index: number) {
    this.loaded = true;
    return this.result[index].url;
  }

The nextBook function is used by the next arrow. As you can see, the code is similar. Reset the slider, increase the index, and check whether we’re at the start or end of the payload.

The prevBook function does both the same and the opposite. The first two lines are the same. The long line of code checks where we are in the payload. Is the index greater than 0? Decrement the index. Otherwise, go to the last one.


  nextBook() {
    this.getCurrentIndex();
    this.resetValues();
    this.currentIndex++;
    this.currentIndex > this.result.length - 1 ? (this.currentIndex = 0) : '';
    this.result[this.currentIndex].status = true;
  }

  prevBook() {
    this.getCurrentIndex();
    this.resetValues();
    this.currentIndex > 0 ? this.currentIndex-- : (this.currentIndex = this.result.length - 1);
    this.result[this.currentIndex].status = true;
  }

  getCurrentIndex() {
    for (var i = 0; i < this.result.length; i++) {
      if (this.result[i].status) this.currentIndex = i;
    }
    this.productInfo = false;
  }

  resetValues() {
    for (var index = 0; index < this.result.length; index++) {
      this.result[index].status = false;
    }
    this.productInfo = false;
  }

Angular Slider Markup and Style

The meat and potatoes are housed inside the slider ID element. If things are loaded, we show content. And if the image is not found, we add a new path to the image src element. All attributes come from the data stream.

Show the book description if productInfo is true. There’s a click function with the logic built right into the markup. I did this because it’s one simple variable toggle. Below that are the next and previous buttons. Both of which use the currentIndex variable. Below that are the radio buttons with a for loop. So, if we have more books, these will grow automatically.

<div class="wrapper element-shadow element-margin-top">
    <div class="slider-bg"></div>
    <div class="tagLine">Top Four AI Books of 2023</div>
    <div id="slider">
      <div class="content">
        <div *ngIf="loaded" class="books-wrapper">
          <img
            onerror="this.onerror=null;this.src='path-to-404-image'"
            [src]="getSliderImage(currentIndex)"
            class="element-shadow"
            alt="{{ result[currentIndex].altText }}"
          />
          <div
            class="product-info"
            [ngClass]="{ 'show-product-info': productInfo }"
          >
            {{ result[currentIndex].description }}
          </div>
          <div class="purchase-info">
            <div>
              <a
                href="{{ result[currentIndex].link }}"
                target="_blank"
                class="purchase-btn element-shadow"
                >Purchase Book</a
              >
              <div (click)="productInfo = !productInfo" class="info-wrapper">
                <span>ℹ</span>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="navigation">
        <div (click)="prevBook()" class="prev"><span>➜</span></div>
        <div (click)="nextBook()" class="next"><span>➜</span></div>
      </div>
    </div>
    <div class="dots">
      <input
        type="radio"
        [checked]="item.status"
        name="arrPos"
        *ngFor="let item of result; let i = index"
        (click)="changeShowcase(i)"
      />
    </div>
  </div>

The styling has an auto generated gradient at the top with extra browser support. The purchaseInfo class is one big nested object for organizational purposes. Inside of the dots class, we’re changing the color of the radio buttons with accent. productInfo is the black overlay that slides in and out.

In Conclusion

There’s so much more we can add here. Transitions between the imagery. We can add a description to each book and display it underneath vs on the book. We could add a star rating powered by Spring Boot so users of this carousel could rate the books. Or, we could even add params to the GET request. Send it to an Express backend to fetch the data. Regardless, I hope you found this useful and can use it in future projects. As is or customized to your liking. The list goes on. Check out my Angular Slider live code example.

3 Trackbacks / Pingbacks

  1. Powerful Angular Accordion to Enhance Your UI - Frontend Development
  2. Custom Angular Data Table Solution - Frontend Development
  3. Full Component Control in this Angular Date Picker - Frontend Development

Leave a Reply

Your email address will not be published.


*