Skip to main content
Version: v7

Loading Photos from the Filesystem

We’ve implemented photo taking and saving to the filesystem. There’s one last piece of functionality missing: the photos are stored in the filesystem, but we need a way to save pointers to each file so that they can be displayed again in the photo gallery.

Fortunately, this is easy: we’ll leverage the Capacitor Preferences API to store our array of Photos in a key-value store.

Preferences API

Begin by defining a constant variable that will act as the key for the store:

export class PhotoService {
public photos: UserPhoto[] = [];
private PHOTO_STORAGE: string = 'photos';

// other code
}

Next, at the end of the addNewToGallery function, add a call to Preferences.set() to save the Photos array. By adding it here, the Photos array is stored each time a new photo is taken. This way, it doesn’t matter when the app user closes or switches to a different app - all photo data is saved.

Preferences.set({
key: this.PHOTO_STORAGE,
value: JSON.stringify(this.photos),
});

With the photo array data saved, create a function called loadSaved() that can retrieve that data. We use the same key to retrieve the photos array in JSON format, then parse it into an array:

public async loadSaved() {
// Retrieve cached photo array data
const { value } = await Preferences.get({ key: this.PHOTO_STORAGE });
this.photos = (value ? JSON.parse(value) : []) as UserPhoto[];

// more to come...
}

On mobile (coming up next!), we can directly set the source of an image tag - <img src="x" /> - to each photo file on the Filesystem, displaying them automatically. On the web, however, we must read each image from the Filesystem into base64 format, using a new base64 property on the Photo object. This is because the Filesystem API uses IndexedDB under the hood. Below is the code you need to add in the loadSaved() function you just added:

// Display the photo by reading into base64 format
for (let photo of this.photos) {
// Read each saved photo's data from the Filesystem
const readFile = await Filesystem.readFile({
path: photo.filepath,
directory: Directory.Data,
});

// Web platform only: Load the photo as base64 data
photo.webviewPath = `data:image/jpeg;base64,${readFile.data}`;
}

After, call this new method in tab2.page.ts so that when the user first navigates to Tab 2 (the Photo Gallery), all photos are loaded and displayed on the screen.

async ngOnInit() {
await this.photoService.loadSaved();
}

That’s it! We’ve built a complete Photo Gallery feature in our Ionic app that works on the web. Next up, we’ll transform it into a mobile app for iOS and Android!