The Favorites Tab
Learn about the code that we will write for the favorite movies page.
We'll cover the following...
Favorited movies
Let’s move on to the final page component in our application that manages all movies that a user may have selected and saved as their favorites.
The component logic
In the src/app/tab3/tab3.page.ts
component class, we add the following changes (highlighted):
Press + to interact
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit, OnDestroy } from '@angular/core';import { FavouriteMoviesService } from '../services/favourite-movies.service';import { MoviedbApiService } from '../services/moviedb-api.service';import { MoviesListenerService } from '../services/movies-listener.service';import { StorageService } from '../services/storage.service';import { environment } from '../../environments/environment';import { Observable, from, of, Subscription } from 'rxjs';import { map } from 'rxjs/operators';@Component({selector: 'app-tab3',templateUrl: 'tab3.page.html',styleUrls: ['tab3.page.scss'],changeDetection: ChangeDetectionStrategy.OnPush})export class Tab3Page implements OnInit, OnDestroy {public favouritesObj$: Observable<any>;public configObj: Subscription;public favouritesExist: boolean;public config: any = {};public selectedGenre: string;public parsedFavourites: Array<any> = [];private favouritesInDescendingOrder: Array<any> = [];public sectionType = 'Favourites';private STORAGE_KEY: string = environment.keys.storage.myMovies;/*** Creates an instance of Tab3Page.*/constructor(private favourites: FavouriteMoviesService,private movies: MoviedbApiService,private movieListener: MoviesListenerService,private storage: StorageService,private cdr: ChangeDetectorRef) {}/*** Angular lifecycle hook - triggered once on component initialization* Here we bootstrap the page with triggering the following methods:* 1. getConfiguration* 2. listenForRemovedMovies*/ngOnInit() {this.getConfiguration();this.listenForRemovedMovies();}/*** Ionic lifecyclehook - triggered AFTER the component view has entered.* Here we trigger the doWeHaveExistingFavourites method for rendering* any saved favourite movies to the component template*/ionViewDidEnter() {this.doWeHaveExistingFavourites();this.cdr.detectChanges();}/*** Angular lifecycle hook - triggered when component is destroyed.* Here we remove any subscriptions/perform garbage collection*/ngOnDestroy() {this.configObj.unsubscribe();}/*** Listens for movies that have been removed and updates the saved favourites accordingly* whilst also saving that back to Ionic Storage for persistence*/private listenForRemovedMovies(): void {this.movieListener.resultListener$.subscribe((data: Array<any>) => {if (this.parsedFavourites.length > 0) {this.favouritesObj$ = of(data).pipe(map(val => {this.parsedFavourites = [...val];this.favouritesInDescendingOrder = [...val].reverse();this.storage.set(this.STORAGE_KEY, JSON.stringify(this.parsedFavourites));return val;}));}});}/*** Retrieves the API URL and API Key details*/private getConfiguration(): void {this.configObj = this.movies.getConfiguration().subscribe((data: any) => {this.config = data;});}/*** Determines if there are existing favourites, if there are they are then parsed and rendered* into the component template*/private doWeHaveExistingFavourites(): void {this.parsedFavourites = [];this.favouritesObj$ = from(this.favourites.doWeHaveExistingFavourites()).pipe(map(val => {let items = val;if (items === null) {this.favouritesExist = false;items = [];} else {this.favouritesExist = true;this.parsedFavourites = [...items];this.favouritesInDescendingOrder = [...items].reverse();this.movieListener.moviesToBeParsed(this.parsedFavourites);}return items;}));}/*** Allows the saved favourites to display films in ascending or descending order*/public displayFilmsInFollowingOrder(ev: any): void {console.dir(ev);const displayOrder = ev.detail.value;if (displayOrder === 'asc') {this.favouritesObj$ = of(this.parsedFavourites);} else {this.favouritesObj$ = of(this.favouritesInDescendingOrder);}}/*** Allows the saved favourites to only display those movies belonging to a specific genre*/public filterMoviesByselectedGenre(selectedGenre: string): void {const movies = [];this.parsedFavourites.filter(item => {if (item.genres.includes(selectedGenre)) {movies.push(item);}});this.favouritesObj$ = of(movies);}}
Our Tab3Page
component logic manages the following functionality for the favorite movies section of the ...