Hi, I am trying to get help with populating a favorites page (list of favored items) in Ionic5 app. It has tabs for films, people, planets and starships and a favorite service for all. I’ve created a new tab for favorites, and so far got it working for films only and unsure how to populate it for the people, planets and starships, which I also want to add. I’ve spent a lot of time researching this but unable to solve it.
Below is the code for favorites.page.ts, which only populates data for films.
import { Component, OnInit } from '@angular/core';
import { Storage } from '@ionic/storage';
import { FavoriteService } from '../../services/favorite.service';
import { ApiService } from '../../services/api.service';
import { forkJoin } from 'rxjs';
@Component({
selector: 'app-favorites',
templateUrl: './favorites.page.html',
styleUrls: ['./favorites.page.scss'],
})
export class FavoritesPage implements OnInit {
films = [];
constructor(private storage: Storage, private favService: FavoriteService, private apiService: ApiService) { }
ngOnInit() {
this.favService.getAllFavoriteFilms().then(data => {
console.log('favs: ', data); // ["1", "5", "3"]
this.loadFilmData(data);
});
}
loadFilmData(favFilms: string[]) {
const observables = [];
// Create an API call for every saved movie ID
for (let id of favFilms) {
observables.push(this.apiService.getFilm(id));
}
// Wait until all observables are finished
forkJoin(observables).subscribe(result => {
console.log('filmd data: ', result);
this.films = result;
})
}
}
Below is favorites.page.html, which shows favorite films.
<ion-header>
<ion-toolbar id="color">
</ion-toolbar>
</ion-header>
<ion-content>
<h1 class="title">Favorite Films</h1>
<ion-item *ngFor="let f of films">
<ion-label>
{{ f.title }}
</ion-label>
</ion-item>
<h1 class="title">Favorite People</h1>
<ion-item *ngFor="let p of people">
<ion-label>
{{ p.name }}
</ion-label>
</ion-item>
<h1 class="title">Favorite Planets</h1>
<ion-item *ngFor="let p of planets">
<ion-label>
{{ s.name }}
</ion-label>
</ion-item>
<h1 class="title">Favorite Starships</h1>
<ion-item *ngFor="let s of starships">
<ion-label>
{{ p.name }}
</ion-label>
</ion-item>
</ion-content>
This is the favorite.service.ts below.
import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage';
const STORAGE_KEY = 'favoriteFilms';
const PLANETS_KEY = 'favoritePlanets';
const PEOPLE_KEY = 'favoritePeople';
const STARSHIPS_KEY = 'favoritesStarships';
@Injectable({
providedIn: 'root'
})
export class FavoriteService {
constructor(private storage: Storage) {
}
getAllFavoriteFilms() {
return this.storage.get(STORAGE_KEY);
}
getAllFavoritePeople() {
return this.storage.get(PEOPLE_KEY);
}
getAllFavoritePlanets() {
return this.storage.get(PLANETS_KEY);
}
getAllFavoriteStarships() {
return this.storage.get(STARSHIPS_KEY);
}
isFavorite(filmId) {
return this.getAllFavoriteFilms().then(result => {
return result && result.indexOf(filmId) !== -1;
});
}
isFavorite1(personId) {
return this.getAllFavoritePeople().then(result => {
return result && result.indexOf(personId) !== -1;
});
}
isFavorite2(planetId) {
return this.getAllFavoritePlanets().then(result => {
return result && result.indexOf(planetId) !== -1;
});
}
isFavorite3(starshipId) {
return this.getAllFavoriteStarships().then(result => {
return result && result.indexOf(starshipId) !== -1;
});
}
favoriteFilm(filmId) {
return this.getAllFavoriteFilms().then(result => {
result = result || [];
result.push(filmId);
return this.storage.set(STORAGE_KEY, result);
});
}
favoritePerson(personId) {
return this.getAllFavoritePeople().then(result => {
result = result || [];
result.push(personId);
return this.storage.set(PEOPLE_KEY, result);
});
}
favoritePlanet(planetId) {
return this.getAllFavoritePlanets().then(result => {
result = result || [];
result.push(planetId);
return this.storage.set(PLANETS_KEY, result);
});
}
favoriteStarship(starshipId) {
return this.getAllFavoriteStarships().then(result => {
result = result || [];
result.push(starshipId);
return this.storage.set(STARSHIPS_KEY, result);
});
}
unfavoriteFilm(filmId) {
return this.getAllFavoriteFilms().then(result => {
if (result) {
var index = result.indexOf(filmId);
result.splice(index, 1);
return this.storage.set(STORAGE_KEY, result);
}
});
}
unfavoritePerson(personId) {
return this.getAllFavoriteFilms().then(result => {
if (result) {
var index = result.indexOf(personId);
result.splice(index, 1);
return this.storage.set(PEOPLE_KEY, result);
}
});
}
unfavoritePlanet(planetId) {
return this.getAllFavoritePlanets().then(result => {
if (result) {
var index = result.indexOf(planetId);
result.splice(index, 1);
return this.storage.set(PLANETS_KEY, result);
}
});
}
unfavoriteStarship(starshipId) {
return this.getAllFavoriteStarships().then(result => {
if (result) {
var index = result.indexOf(starshipId);
result.splice(index, 1);
return this.storage.set(STARSHIPS_KEY, result);
}
});
}
}
And this is the api.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(private http: HttpClient) { }
getFilms() {
return this.http.get('https://swapi.dev/api/films');
}
getFilm(id) {
return this.http.get(`https://swapi.dev/api/films/${id}`);
}
getPlanets() {
return this.http.get('https://swapi.dev/api/planets');
}
getPlanet(id) {
return this.http.get(`https://swapi.dev/api/planets/${id}`);
}
getStarships() {
return this.http.get('https://swapi.dev/api/starships');
}
getStarship(id) {
return this.http.get(`https://swapi.dev/api/starships/${id}`);
}
//referred to code below from https://github.com/herbae/starwarsapp, for some of the code on this page
getPeople() {
return this.http.get('https://swapi.dev/api/people');
}
getPerson(id) {
return this.http.get(`https://swapi.dev/api/people/${id}`);
}
}
So what I need to do is add favorite data for the other 3 categories (people, planets, starships), so as they will display under films favorites, all in one page. This is a snapshot of how it should look, but can only get films data to display.