Using Ionic Storage

Learn how to use a custom Ionic storage service in Ionic applications.

The home component

Let’s now turn our attention to implementing this service within our HomePage component class, situated at movies-app/src/app/home/home.page.ts (amendments to this class are highlighted):

Press + to interact
/**
*
* HomePage
*
* This class manages the logic and rendering for the movies app
*/
import { Component } from '@angular/core';
import { Platform, ToastController } from '@ionic/angular';
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
import { StorageService } from '../services/storage.service';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
public form: FormGroup;
public storageKey = 'MoviesObj';
public isData = false;
public storedData: Array<any> = [];
public movies: Array<any> = [];
/**
* Creates an instance of HomePage
*/
constructor(private storage: StorageService,
public fb: FormBuilder,
private toast: ToastController,
private platform: Platform) {
this.platform
.ready()
.then(() => {
this.renderMovies();
});
this.form = fb.group({
movieName: ['', Validators.required]
});
this.clearFieldValues();
}
public renderMovies(): void {
this.storage
.get(this.storageKey)
.then((data) => {
if (data && data.length > 0) {
const existingData = Object.keys(data).length;
if (existingData !== 0) {
this.storedData = data;
this.isData = true;
}
this.setMovies(this.storedData);
}
})
.catch((error: any) => {
console.dir(error);
});
}
public setMovies(data: Array<any>): void {
let k;
this.movies = [];
for (k in data) {
this.movies.push({
movie: data[k].movie
});
}
}
public saveMovie(): void {
const movieName: string = this.form.get('movieName').value;
let i = 0,
k: any;
// Determine if movie has already been added to the array
for (k in this.storedData) {
if (this.storedData[k].movie === movieName) {
i++;
}
}
if (i === 0) {
this.movies.push({
movie : movieName
});
this.storeMovie(this.movies, movieName);
} else {
const message = `The movie ${movieName} has already been stored. Please enter a different movie title.`;
this.storageNotification(message);
}
}
public storeMovie(movies: Array<any>, movie: string): void {
const moviesStored = movies;
this.storage
.set(this.storageKey, moviesStored)
.then(() => {
this.renderMovies();
const message = `The movie title ${movie} was added successfully`;
this.clearFieldValues();
this.storageNotification(message);
})
.catch(() => {
const message = `Whoops! Something went wrong. The movie title ${movie} was NOT added`;
this.storageNotification(message);
});
}
private get(): Promise<any> {
return this.storage.get(this.storageKey);
}
public remove(movieName: string): void {
this.get().then((data: Array<any>) => {
console.dir(data);
let movies = data;
data.forEach((item, index) => {
if (item.movie === movieName) {
movies.splice(index, 1);
}
});
// While we have data
if (data.length >= 0) {
this.update(movies, movieName);
}
if (data.length === 0) {
movies = null;
this.storedData = [];
this.movies = [];
}
})
.catch((error: any) => {
console.dir(error);
});
}
private update(movies: Array<any>, movie: string): void {
this.storage
.set(this.storageKey, movies)
.then(() => {
this.renderMovies();
const message = `The movie title ${movie} was successfully removed`;
this.clearFieldValues();
this.storageNotification(message);
})
.catch((error: any) => {
console.dir(error);
});
}
private clearFieldValues(): void {
this.form.get('movieName').setValue('');
}
public clear(): void {
this.storage
.remove(this.storageKey)
.then(() => {
this.storedData = [];
this.movies = [];
this.isData = false;
const message = `All movies were successfully removed`;
this.clearFieldValues();
this.storageNotification(message);
})
.catch((error: any) => {
console.dir(error);
});
}
private async storageNotification(displayMessage: string): Promise<any> {
const notification = await this.toast.create({
message : displayMessage,
duration : 3000
});
notification.present();
}
}

The component logic

Our HomePage component class imports the Storage service that we created earlier in this chapter on line 10, along with selected Angular Forms modules on line 9. This will be used in a reactive capacity to programmatically manage the input field in the component view (we’ll cover this shortly) and the Platform and ToastController modules from @ionic/angular on line 8. We’ll use these to respectively determine whether the platform the application is running on has been fully initialized and is available to generate Toast notifications, modal window like messages, and so on).

Following this, some properties are defined within the HomePage component class, starting on line 18, to help manage the application’s movies-related data.

Inside the class constructor on line 27, we call the renderMovies method within the platform ready method to ensure that any saved movies will be rendered for display within the component view. Within the ...