3d cartoon hands holding a phone

Unlock full course by purchasing a membership

Lesson 7

Only Allow One Photo Per Day

Using a stream for a conditional

STANDARD

Only Allow One Photo Per Day

In this lesson, we are going to implement a reasonably simple feature but one that is part of the core concept of this application: to take one photo each day. This gives us an interesting opportunity to think about streams and reactive programming.

We are really only aiming to achieve one goal here:

  • If a photo has already been taken that day, disable the take photo button

We store dates with our photos already so it seems like it should be reasonably easy. You might consider that the above doesn’t seem very secure - just disabling a button doesn’t really prevent someone from doing something. However, this is a totally local application - if the user wants to hack around with the client side code so they can bypass the disabled button and take more than one photo a day it doesn’t really matter.

Getting the data from the stream

The button we want to disable is in our HomeComponent, and in that component we have a stream of the photos$ data that we need to check the date on:

  photos$ = this.photoService.photos$.pipe(
    map((photos) =>
      photos.map((photo) => ({
        ...photo,
        safeResourceUrl: this.sanitizer.bypassSecurityTrustResourceUrl(
          photo.path
        ),
      }))
    )
  );

One thing that you could do, and perhaps this might come to you more naturally if you are used to an imperative style of programming, is to create a class member that is a boolean flag like this:

hasTakenPhotoToday = false;

Then perhaps in an OnInit hook you subscribe to photos$ to do the check and set it appropriately:

this.photos$.subscribe((photos) => {
    this.hasTakenPhotoToday = // check dates on photos;
});

However, I would not recommend doing this. Again, we want to avoid manual subscribes wherever possible and there isn’t a need for one here.

There are actually different ways we could handle this. One method that would be fine, but which we are not doing, is to use a pipe. In the template, you might do something like this:

<ion-button (click)="photoService.takePhoto()" [disabled]="vm.photos | hasTakenPhotoToday">
    <ion-icon name="camera-outline" slot="icon-only"></ion-icon>
</ion-button>
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).