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>
Changes to Home.vue Component
// aws import
import { Storage } from "@aws-amplify/storage";
// new component
import ImageRender from "@/components/ImageRender.vue";
<!-- 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>
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 })
);
};
Changes to the EntryForm.vue Component
<!-- added to template -->
<ion-item>
<input type="file" @change="onChange" />
</ion-item>
/**
* 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;
};