Skip to content

Instantly share code, notes, and snippets.

@saionaro
Last active October 13, 2020 12:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save saionaro/7ee0e2c02749e2729dc429c9e9bfa7f3 to your computer and use it in GitHub Desktop.
Save saionaro/7ee0e2c02749e2729dc429c9e9bfa7f3 to your computer and use it in GitHub Desktop.
A direct file uploading, react native edition
//...
// some interfaces imports skipped
//...
const createDirectUploadMutation = `
mutation createDirectUploadMutation(
$filename: String!
$byteSize: Int!
$contentType: String!
) {
createDirectUpload(
input: {
filename: $filename
byteSize: $byteSize
contentType: $contentType
}
) {
directUpload {
blobId
headers
signedBlobId
url
}
}
}
`;
//...
// skip some interface declarations
// two most important can be found at the end of file
//...
export class Uploader implements IUploader {
public constructor(
private client: IApiClient,
private file: IFile,
) {}
public async upload(): Promise<IUploadFileResult> {
const response: ICreateDirectUploadResult = await this.client.query( // lets say - it just the fetch with some tweaks
createDirectUploadMutation,
this.file,
);
//...
// some boring validation logic skipped
//...
const { directUpload } = response.createDirectUpload;
const blob = await this.toBlob(this.file.uri);
await this.performUpload(blob, directUpload);
return {
signedId: directUpload.signedBlobId,
id: directUpload.blobId,
};
}
private async toBlob(uri: string): Promise<Blob> {
return await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = () => resolve(xhr.response);
xhr.onerror = () => reject(new UploadFileError("notFound"));
xhr.responseType = "blob";
xhr.open("GET", uri, true);
xhr.send(null);
});
}
private performUpload(
blob: Blob,
directUpload: IDirectUpload,
): Promise<void> {
return new Promise((resolve, reject) => {
const req = new XMLHttpRequest();
const headers = JSON.parse(directUpload.headers);
req.open("PUT", directUpload.url, true);
for (let header in headers) {
req.setRequestHeader(header, headers[header]);
}
req.onload = () => resolve();
req.onerror = () => reject(Err(new UploadFileError("transportError")));
req.send(blob);
});
}
}
interface IFile {
filename: string;
byteSize: number;
contentType: string;
uri: string;
}
interface IDirectUpload {
blobId: string;
headers: string;
signedBlobId: string;
url: string;
}
import { Uploader } from "src/Uploader";
import { ApiClient } from "src/ApiClient";
const file = {
filename: "dev.to", // file name
contentType: "image/jpeg", // file content type
uri: "path/to/local/file", // local file path at your device
byteSize: 2019, // size in bytes
};
const apiClient = new ApiClient(...);
const uploaderInstance = new Uploader(apiClient, file);
const responce = await uploaderInstance.upload();
const { signedId } = responce;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment