Launch sale! Get 30% OFF expires in 126:46:22

Existing member? Log in and continue learning

See if you like it, start the course for free!

Unlock full course by purchasing a membership
Creating a Slideshow
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
import { Component, inject, input } from '@angular/core';import { PhotoData } from '../shared/interfaces/photo';import { IonButton, IonButtons, IonContent, IonHeader, IonIcon, IonTitle, IonToolbar, ModalController,} from '@ionic/angular/standalone';import { addIcons } from 'ionicons';import { close } from 'ionicons/icons';
@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> `, imports: [ IonHeader, IonToolbar, IonTitle, IonButtons, IonButton, IonIcon, IonContent, ],})export class SlideshowComponent { modalCtrl = inject(ModalController); photos = input.required<PhotoData[]>();
constructor() { addIcons({ close }); }}
All this should be reasonably familiar. We are setting up a component that we
will display as a modal and we are setting up an input
so that can pass in our
photos.
The interesting part will come next.
Displaying one photo at a time
The next step is to take the photos we are passing in as an input, and somehow convert them into a stream that emits one photo at a time for us to display.
export class SlideshowComponent { modalCtrl = inject(ModalController); photos = input.required<PhotoData[]>();
reversedPhotos = computed(() => [...this.photos()].reverse());
currentPhoto$ = toObservable(this.reversedPhotos).pipe( // Emit one photo at a time switchMap((photos) => from(photos)), concatMap((photo) => // Create a new stream for each individual photo of(photo).pipe( // Creating a stream for each individual photo // will allow us to delay the start of the stream delay(500), ), ), ); currentPhoto = toSignal(this.currentPhoto$);
constructor() { addIcons({ close }); }}
We have our photos
input signal that gets the photo values to begin with, then
we derive a reversedPhotos
signal from that since we want to display the
photos in reverse order.
But then we convert that reversedPhotos
signal into an observable stream that
will emit one photo at a time from our photos array, and then we convert that
result back into a signal.
Whilst the detour/conversion into observables here isn’t strictly required, I find observables to be a much more reliable and powerful solution than relying on things like
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).