Axios seems to work quite fine for file uploads, but, since it’s a Front end applications, I wanted to avoid using a third party lib for a simple file upload task.
My requirements are to be able to upload a file and get update on progress, file potentially 1-3GB in size.
Note, I can’t use FormData
because, I eventually want to use S3 presigned urls
which use PUT
and expect raw binary.
Other than using axios, I came across 2 options:
- Fetch
- Https module
While uploading with fetch
seems to be simple, there doesn’t seem to be a way to get progress update.
And the hurdle I came with https
is that it seems to need a Readstream
, and in browser I can’t use the fs
module. So, just seeing the interfaces, I did a hacky bit of code like this(taking a similar example, but, this one uses form data):
import https from 'https';
// file = event.target.files[0]
export async function uploadFile(
url: string,
file: File,
onProgress: () => void = noOp,
method = REQ.PUT,
) {
let progressDataLength = 0;
let data = "";
return new Promise((resolve, reject) => {
const req = https.request(
{
hostname: url,
method: method,
headers: {
"Content-Type": file.type,
"Content-Length": file.size,
},
},
function (res) {
res.on("data", (chunk) => {
progressDataLength += chunk.size;
data += chunk;
onProgress();
console.log("Total received: ", `${chunk.size}/${file.size}`);
});
res.on("end", () => {
resolve("Mydata: " + data);
});
},
);
// MY HACKY CODE BIT
const startConversionTime = new Date().getTime();
Readable.from(Buffer.from(await file.arrayBuffer())).pipe(req);
console.log(
"Total conversion time taken: ",
new Date().getTime() - startConversionTime,
);
req.end();
});
}
While this particular code produced the error below, I’m not sure if this is even legit at all? ( Is the conversion done right? and, I can’t really find examples of File
being converted to readable stream )
TypeError: The “listener” argument must be of type Function. Received type object
What are my options of implementing this function and how can it be done?