CodewCaro.
In order to upload an asset to your AWS S3 bucket through a signed URL you first need to create a filereader.
If you have several files that you want to upload you could create a function that takes in the assets and then do a forEach on them.
File path: src > components > FileUpload > FileUpload.jsx
import React, { useState } from 'react';
const [files, setFiles] = useState([]);
function uploadHandler(assets) {
assets.forEach((asset) => {
var reader = new FileReader();
reader.readAsArrayBuffer(asset);
reader.onload = () => {
asset.bufferedFile = reader.result;
};
});
setFiles(Object.values(assets));
}
In the function where you upload functionality is done you could then again loop on each file to then call your mutation
File path: src > components > FileUpload > FileUpload.jsx
function onUploadAssets(files) {
files.forEach((file) => {
createNewAsset(file);
});
}
If you want to perform an upload request with a signed URL you do the following
File path: src > apollo > mutations > UploadRequest.ts
import { gql } from '@apollo/client';
export const UPLOAD_REQUEST = gql`
mutation UploadRequest($filename: String!) {
uploadRequest(filename: $filename) {
path
signedUrl
}
}
`;
Then include the UploadRequest mutation like this
File path: src > components > FileUpload > FileUpload.jsx
const [UploadRequest, { loading: uploadLoading, error: uploadError }] =
useMutation(UPLOAD_REQUEST);
For the mutation that actually creates the asset you write the following in your mutations folder
File path: src > apollo > mutations > UploadRequest.ts
import { gql } from '@apollo/client';
export const CREATE_ASSET = gql`
mutation uploadAsset($path: String!) {
uploadAsset($path: $path) {
success
}
}
`;
Create a const for your mutation in FileUpload.jsx
File path: src > components > FileUpload > FileUpload.jsx
const [createAsset, { loading: createAssetLoading, error: createAssetError }] = useMutation(
CREATE_ASSET,
{
onCompleted: (uploadAsset) => {
if (uploadAsset.uploadAsset.success) {
console.log('Successfully created asset!');
//Refresh page on completed mutation
window.location.reload(false);
}
},
onError: (error) => {
console.log('Something went wrong when creating asset', createAssetError);
}
}
);
This is where you perform your PUT
File path: src > components > FileUpload > FileUpload.jsx
import { CREATE_ASSET } from '../../apollo/mutations/UploadSecureAsset';
import { UPLOAD_REQUEST } from '../../apollo/mutations/UploadRequest';
import { useMutation } from '@apollo/client';
const [UploadRequest, { loading: uploadLoading, error: uploadError }] =
useMutation(UPLOAD_REQUEST);
const createNewAsset = (file, tags) => {
UploadRequest({
variables: {
filename: file.name
}
}).then((uploadRes) => {
fetch(uploadRes.data.uploadRequest.signedUrl, {
method: 'PUT',
headers: {
'content-type': file.type
},
body: file.bufferedFile // Base64 of file
}).then((putRes) => {
// TODO: Change when we can do PUT to the actual s3
if (putRes.status === 200) {
createAsset({
variables: {
path: uploadRes.data.uploadRequest.path
}
});
} else {
console.log('Failed to upload asset');
}
});
});
};