DEV Community

Cover image for Ionic Vue JS AWS Amplify Authentication CRUD Tutorial Pt 4, File, Image Upload with Storage with S3
Aaron K Saunders
Aaron K Saunders

Posted on

2

Ionic Vue JS AWS Amplify Authentication CRUD Tutorial Pt 4, File, Image Upload with Storage with S3

This is a continuation of a video series on using AWS Amplify Datastore with Vue JS and Ionic Framework for the user interface. We did the setup, user authentication/account creation, and querying data in the first two parts of the video.

In the fourth video we cover uploading and retrieving files, specifically image data from AWS Amplify Storage.

This blog post is to provide the source code from the project.

Please see the entire tutorial videos by using the link below

New Component ImageRender.vue

<template>
  <div v-if="imageKey"><img :src="signedURL" /></div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
import { Storage } from "@aws-amplify/storage";
export default defineComponent({
  name: "ImageRender",
  props: ["imageKey"],
  setup(props: any) {
    const signedURL = ref<any>(null);
    props.imageKey && Storage.get(props.imageKey, { download: true }).then((result: any) => {
      signedURL.value = URL.createObjectURL(result.Body);
    });
    return {
      signedURL
    };
  }
});
</script>

<style scoped>
</style>
Enter fullscreen mode Exit fullscreen mode

Changes to Home.vue Component

// aws import
import { Storage } from "@aws-amplify/storage";

// new component
import ImageRender from "@/components/ImageRender.vue";
Enter fullscreen mode Exit fullscreen mode
<!-- changed template to cards -->
<ion-list>
  <ion-card v-for="taskData in tasks" :key="taskData.id">
    <ion-card-content>
            <!-- Added component to render image -->
      <div style="width:auto">
        <image-render :imageKey="taskData?.file"></image-render>
      </div>
      <ion-label class="ion-text-wrap">
        <p>{{ taskData.title }}</p>
        <p>{{ taskData.description }}</p>
        <p id="id">{{ taskData.id }}</p>
        <div
          class="ion-float-right ion-padding"
          style="padding-right:0px"
        >
          <ion-button
            style="zoom: 0.8"
            @click="showInputModal(taskData)"
            >EDIT</ion-button
          >
          <ion-button
            style="zoom: 0.8"
            @click="deleteData(taskData)"
            color="danger"
            >DELETE</ion-button
          >
        </div>
      </ion-label>
    </ion-card-content>
  </ion-card>
</ion-list>
Enter fullscreen mode Exit fullscreen mode
const createData = async (data: any) => {
  console.log(data);

  // check for file to add to the object, use the filename
    // as the key when you save the file
  const fileSaveResp = data.file
    ? ((await Storage.put(encodeURIComponent(data.file.name), data.file)) as any)
    : null;
  return await DataStore.save(
    new Task({ ...data, file: fileSaveResp?.key })
  );
};
Enter fullscreen mode Exit fullscreen mode

Changes to the EntryForm.vue Component

<!-- added to template -->
<ion-item>
  <input type="file" @change="onChange" />
</ion-item>
Enter fullscreen mode Exit fullscreen mode
/**
 * if the user has selected a file, save file 
 * object to form data
 */
const onChange = async (e: any) => {
  const file = e.target.files[0];
  formData.value.file = file;
};
Enter fullscreen mode Exit fullscreen mode

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay