Skip to content

Instantly share code, notes, and snippets.

@DanyF-github
Created January 8, 2021 10:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanyF-github/a57f0c68307d9b62c075b6f919d4b8ce to your computer and use it in GitHub Desktop.
Save DanyF-github/a57f0c68307d9b62c075b6f919d4b8ce to your computer and use it in GitHub Desktop.
// client/src/component/HomeworkFileForm.tsx
import React from 'react';
import { useMutation, useQuery } from '@apollo/client';
import {
ADD_HOMEWORK_FILE,
PRESIGN_HOMEWORK_FILE_UPLOAD,
} from '../../data/mutations';
import { GET_HOMEWORK } from '../../data/queries';
import { Homework } from '../../models';
// this components receives the uuid of the homework and the authentication token as properties
const HomeworkFileForm = ({ uuid, token }: { uuid: string; token: string }) => {
// create a reference of the html element
let homeworkFileRef: HTMLInputElement;
// use the uuid to retrieve the information of the homework
const { data, loading, error } = useQuery<
{ homework: Homework },
{ uuid: string }
>(GET_HOMEWORK, {
variables: {
uuid
}
});
// setup the mutate functions for presiging the file and for adding the reference to the database
const [presignHomeworkFileUpload] = useMutation(PRESIGN_HOMEWORK_FILE_UPLOAD);
const [addHomeworkFile] = useMutation(ADD_HOMEWORK_FILE);
render the component
return (
<>
{loading && <p>Loading...</p>}
{error && <p>Error!</p>}
{data && (
<>
<p>Description: {data.homework.description}</p>
<form
onSubmit={async (e) => {
e.preventDefault();
try {
// get the file from the html element reference
const file =
homeworkFileRef &&
homeworkFileRef.files &&
homeworkFileRef.files[0];
// make sure a file was provided
if (!file) {
throw new Error('file is not defined');
}
// get the presign informatio from the server
const { data } = await presignHomeworkFileUpload({
variables: {
fileName: `homeworks/uuid/${Date.now()}`,
isPublic: true,
token,
},
});
// parse the stringified JSON
const imageData = JSON.parse(data.presignDocument);
// create a form programatically for sending the file to S3
const formData = new FormData();
// add the required headers
formData.append('Content-Type', file?.type);
formData.append('acl', 'public-read');
// add the signing information
Object.keys(imageData.fields).forEach((key) => {
formData.append(key, imageData.fields[key]);
});
// and finally add the file
formData.append('file', file);
// use fetch to send a POST requests to S3
const result = await fetch(imageData.url, {
method: 'POST',
body: formData,
});
// if the file was uploaded sucessfully then add the file information to the database
if (result.status >= 200 && result.status <= 299) {
addHomeworkFile({
variables: {
url: imageData.url + '/' + imageData.fields.Key,
uuid,
token,
},
});
}
} catch (err) {
console.error('An error ocurred', err);
}
}}
>
<input
id="homeworkFile"
type="file"
name="homeworkFile"
ref={(node: HTMLInputElement) => (homeworkFileRef = node)}
/>
<button type="submit">Send</button>
</form>
</>
)}
</>
);
};
export default HomeworkFileForm;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment