Skip to content

Instantly share code, notes, and snippets.

@mikevercoelen
Created July 22, 2021 04:33
Show Gist options
  • Save mikevercoelen/27befa2381cb48549bbbe83d061a26db to your computer and use it in GitHub Desktop.
Save mikevercoelen/27befa2381cb48549bbbe83d061a26db to your computer and use it in GitHub Desktop.
Upload file with signed URL + endpoint
import _ from 'lodash'
import { gql } from '@apollo/client'
const THROTTLE_CAP = 750
const signFileUploadMutation = gql`
mutation SignFileUpload (
$fileName: String!
$type: FileUploadType!
) {
signFileUpload(
fileName: $fileName
type: $type
) {
bucketFolder
bucketName
fileBucketLocation
uniqueFileName
signedUrl
url
}
}
`
export const getSignedUrl = async (apolloClient, fileName, type) => {
const signedUrlRes = await apolloClient.mutate({
mutation: signFileUploadMutation,
variables: {
fileName,
type
}
})
return signedUrlRes?.data?.signFileUpload
}
const xhrWithProgress = ({
url,
method = 'PUT',
onProgress,
file
}) => new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(xhr)
} else {
reject(xhr)
}
}
}
const handleProgress = (e) => {
if (e.lengthComputable) {
const percentage = (e.loaded / file.size) * 100
onProgress(percentage)
}
}
if (onProgress) {
xhr.upload.addEventListener('progress', _.throttle(handleProgress, THROTTLE_CAP))
}
xhr.onerror = (error) => {
reject(error || new Error('An error happened with uploading'))
}
xhr.open(method, url)
xhr.send(file)
})
export const uploadFile = async (apolloClient, file, type, onProgress) => {
const res = await getSignedUrl(apolloClient, file.name, type)
const signedUrl = res?.signedUrl
const url = res?.url
if (!signedUrl || !url) {
throw new Error('Unknown')
}
await xhrWithProgress({
url: signedUrl,
method: 'PUT',
onProgress,
file
})
return res
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment