Search docs/

Loading Photos from the Filesystem

Contents

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 Storage API to store our array of Photos in a key-value store.

Storage API

Begin by defining a constant variable that will act as the key for the store at the top of the usePhotoGallery function in src/composables/usePhotoGallery.ts:

const PHOTO_STORAGE = "photos";
CopyCopied

Then, import the Storage API to get access to methods for reading and writing to device storage:

export function usePhotoGallery() {
  const { Camera, Filesystem, Storage } = Plugins;
  const photos = ref<Photo[]>([]);
  const PHOTO_STORAGE = "photos";
CopyCopied

Next, add a cachePhotos function that saves the Photos array as JSON to file storage:

const cachePhotos = () => {
  Storage.set({
    key: PHOTO_STORAGE,
    value: JSON.stringify(photos.value)
  });
}
CopyCopied

Next, use the Vue watch function to watch the photos array. Whenever the array is modified (in this case, taking or deleting photos), trigger the cachePhotos function. Not only do we get to reuse code, but it also doesn’t matter when the app user closes or switches to a different app - photo data is always saved.

watch(photos, cachePhotos);
CopyCopied

Now that the photo array data is saved, create a function to retrieve the data when Tab2 loads. First, retrieve photo data from Storage, then each photo's data into base64 format:

const loadSaved = async () => {
  const photoList = await Storage.get({ key: PHOTO_STORAGE });
  const photosInStorage = photoList.value ? JSON.parse(photoList.value) : [];

  for (const photo of photosInStorage) {
    const file = await Filesystem.readFile({
        path: photo.filepath,
        directory: FilesystemDirectory.Data
    });
    photo.webviewPath = `data:image/jpeg;base64,${file.data}`;
  }

  photos.value = photosInStorage;
}
CopyCopied

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, because the Filesystem API stores them in base64 within IndexedDB under the hood.

Finally, we need a way to call the loadSaved function when the Photo Gallery page is loaded. To do so, use the Vue mounted lifecycle hook. First, import onMounted from Vue:

import { ref, onMounted, watch } from 'vue';
CopyCopied

Then, within the usePhotoGallery function, add the onMounted function and call loadSaved:

onMounted(loadSaved);
CopyCopied

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!

Previous
Saving Photos on Filesystem
Next
Adding Mobile