3d cartoon hands holding a phone

Unlock full course by purchasing a membership

Lesson 9

Creating a Slideshow

Displaying each photo one at a time

STANDARD

Creating a Slideshow

Although we will still have a few refinements remaining after this, in this lesson we are going to tackle the last significant feature of this application: the ability to play a slideshow of all of the photos that have been taken.

We will start with the first photo taken, and then display each photo rapidly in succession. The core idea here is reasonably straightforward, but the way in which we will achieve this using streams is actually kind of interesting and challenging. If you’re struggling with the concept of observables and streams a little, don’t fret too much over this lesson. If you’re enjoying streams and looking for a challenge, then you’re in for a treat.

Create the Slideshow Component

Create a new file at src/app/slideshow/slideshow.component.ts and add the following:

import { CommonModule } from '@angular/common';
import {
  ChangeDetectionStrategy,
  Component,
  Input,
  NgModule,
} from '@angular/core';
import { IonicModule, ModalController } from '@ionic/angular';
import { BehaviorSubject } from 'rxjs';
import { Photo } from '../shared/interfaces/photo';

@Component({
  selector: 'app-slideshow',
  template: `
    <ion-header>
      <ion-toolbar color="danger">
        <ion-title>Play</ion-title>
        <ion-buttons slot="end">
          <ion-button (click)="modalCtrl.dismiss()">
            <ion-icon name="close" slot="icon-only"></ion-icon>
          </ion-button>
        </ion-buttons>
      </ion-toolbar>
    </ion-header>
    <ion-content> </ion-content>
  `,
  styles: [
    `
      :host {
        height: 100%;
      }
    `,
  ],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SlideshowComponent {
  currentPhotos$ = new BehaviorSubject<Photo[]>([]);

  constructor(protected modalCtrl: ModalController) {}

  @Input() set photos(value: Photo[]) {
    this.currentPhotos$.next([...value].reverse());
  }
}

@NgModule({
  declarations: [SlideshowComponent],
  imports: [IonicModule, CommonModule],
  exports: [SlideshowComponent],
})
export class SlideshowComponentModule {}

A lot of this should be reasonably familiar. We have the basic structure of an Ionic page, this is going to be displayed as a modal so we inject the ModalController and we also have a button in the template to trigger a dismiss.

The strange part is this:

  @Input() set photos(value: Photo[]) {
    this.currentPhotos$.next([...value].reverse());
  }

Usually, our inputs would look like this:

  @Input() photos!: Photo[];

But this time we are using a setter.

Getters and Setters

Getters and setters are OOP concepts that are a default feature of TypeScript. If you don’t know what they are I would recommend doing a little research, but the key idea is as follows.

If we have an object created from a class, we could access (or “get”) a class member on that like this:

myObject.greeting

If we wanted to change the class member (or “set” it) we could do this:

myObject.greeting = 'hello'

The idea with getters and setters is that it allows us to add additional logic to this process. For example, if we set up a getter like this in our class:

get welcome(){
    return `${this.something}, ${this.name}`
}

When we access myObject.welcome it will return us the result of the function above. Likewise with a setter, if we had a setter like this:

#name: string;

set name(name: string){
    if(name !== 'Josh'){
        this.#name = name;
    }
}

This logic would be used when we try to set the name:

myObject.name = 'Josh'

Except, in this case it won’t let me set the name if the value is Josh. Our example for the SlideshowComponent is a little less silly:

  currentPhotos$ = new BehaviorSubject<Photo[]>([]);

  @Input() set photos(value: Photo[]) {
    this.currentPhotos$.next([...value].reverse());
  }
STANDARD
Key

Thanks for checking out the preview of this lesson!

You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).