Code Examples

See how to use the UploadClient JS library in different scenarios

All the following examples assume that you have installed the client-library and have a file input somewhere in your HTML code. For example:

<input id="file-input" type="file"/>

Initializing the library

Before you can upload files, you must initialize the client library with your API key

// NPM users only
import UploadClient from "@betterstack/upload-client";
// Init upload client
const UC = new UploadClient({
apiKey: "<YOUR_API_KEY>",
});
// Change API key if needed
UC.setApiKey("<YOUR_API_KEY>");

Upload using promises

The simplest way to use the library is to initialize it and upload a file using the promise interface

const file = document.getElementById("file-input").files[0];
// Create upload task
const task = UC.upload({
providerId: "<YOUR_PROVIDER_ID>",
files: [{ file: file }]
});
// Start upload with promise
task.start()
.then((uploaded) => {
const uploadedFile = uploaded[0];
console.log(uploadedFile.key); // Uploaded path
console.log(uploadedFile.file); // Uploaded file
})
.catch((e) => {
console.log(e.code); // Error code
console.log(e.message); // Error message
// See all errors on 'Error Handling' page
});

Async / Await

Using the async / await syntax allows you to write much more readable code that's ultimately easier to manage. The remainder of the code examples will use this method instead of promises directly.

async function uploadFile() {
const file = document.getElementById("file-input").files[0];
const task = UC.upload({
providerId: "<YOUR_PROVIDER_ID>",
files: [{ file: file }]
});
try {
const uploaded = await task.start();
const uploadedFile = uploaded[0];
console.log(uploadedFile.key); // Uploaded path
console.log(uploadedFile.file); // Uploaded file
}
catch (e) {
console.log(e.code); // Error code
console.log(e.message); // Error message
}
}

Form submit

// Somewhere in your HTML
// <form id="form">
// <input id="file-input" type="file"/>
// </form>
const form = document.getElementById("form");
form.addEventListener("submit", async (e) => {
e.preventDefault();
const file = document.getElementById("file-input")[0];
const task = UC.upload({
providerId: "<YOUR_PROVIDER_ID>",
files: [{ file: file }]
});
try {
const uploaded = await task.start();
const uploadedFile = uploaded[0];
console.log(uploadedFile.key); // Uploaded path
console.log(uploadedFile.file); // Uploaded file
}
catch (e) {
console.log(e.code); // Error code
console.log(e.message); // Error message
}
});

React component

This example shows a simple component that will automatically upload files when selected by a user

import React from "react";
class UploadInput extends React.Component {
state = { progress: 0 }
change = async (e) => {
// Get files in input
const files = e.target.files;
// Verify file has been selected
if (files.length === 0) return;
// Create upload task
const task = UC.upload({
providerId: "<YOUR_PROVIDER_ID>",
files: [{ file: file }]
});
// Track upload progress
task.onProgress((e) => {
this.setState({ progress: Math.round(e.loadedPercent) });
});
// Start upload
try {
const uploaded = await task.start();
const uploadedFile = uploaded[0];
console.log(uploadedFile.key); // Uploaded path
console.log(uploadedFile.file); // Uploaded file
}
catch (e) {
console.log(e.code); // Error code
console.log(e.message); // Error message
}
}
render() {
return (
<div>
<input type="file" onChange={this.change}/>
<p>Upload progress: {this.state.progress}%</p>
</div>
);
}
}

Upload multiple files

async function uploadFile() {
// <input id="file-input" type="file" multiple/>
const inputFiles = document.getElementById("file-input");
const files = [];
for (let i = 0; i < inputFiles.length; i++) {
files[i] = { file: inputFiles[i] };
}
const task = UC.upload({
providerId: "<YOUR_PROVIDER_ID>",
files: files,
});
try {
const uploaded = await task.start();
uploaded.forEach((item) => {
console.log(item.key); // Uploaded path
console.log(item.file); // Uploaded file
});
}
catch (e) {
console.log(e.code); // Error code
console.log(e.message); // Error message
}
}

Tracking upload progress

const file = document.getElementById("file-input")[0];
const task = UC.upload({
providerId: "<YOUR_PROVIDER_ID>",
files: [{ file: file }]
});
task.onProgress((e) => {
// Total loaded % from 0 - 100
console.log(e.loadedPercent);
// Total bytes to upload and total bytes uploaded
console.log(e.totalBytes, e.loadedBytes);
// Array of total bytes for each file + uploaded bytes and % of each file
console.log(e.filesBytes, e.filesLoadedBytes, e.filesLoadedPercent);
});

Set custom upload path

By default, if you do not supply a key for the uploaded file, it will be placed in your base storage folder with the current file name. You can modify the base storage folder by editing your storage provider's "Upload Path Prefix" setting. It's recommend that you set a path prefix to prevent malicious clients from uploading files anywhere in your storage bucket.

Supplying an upload key as shown in the example below will result in it being added onto your base storage folder. For example if you set your "Upload Path Prefix" to images/ and you supplied a key of logos/main.png, the final upload path would be images/logos/main.png.

const file = document.getElementById("file-input")[0];
const task = UC.upload({
providerId: "<YOUR_PROVIDER_ID>",
files: [
{
file: file,
key: "logos/main.png",
}
]
});

Set custom upload permission

Upload permissions are controlled by an ACL which is essentially a pre-defined set of permissions. See the list of ACL values available for AWS S3. Digitalocean spaces supports only 2 ACL values, private and public-read. By default, an upload is private if no ACL value is supplied.

You can set a default ACL value by editing your storage provider settings and supplying a value for the "Upload ACL" setting. Supplying an ACL value in your code as shown above will override your default provider ACL value.

const file = document.getElementById("file-input")[0];
const task = UC.upload({
providerId: "<YOUR_PROVIDER_ID>",
files: [
{
file: file,
acl: "public-read",
}
]
});

No errors on failed uploads

When uploading multiple files at once, each file is uploaded separately. By default, if any file fails to upload, the entire upload operation will throw an error. This may result in some files being uploaded already. This behaviour can be disabled so that no errors are thrown and after you can verify which files have been successfully uploaded.

async function uploadFiles() {
// <input id="file-input" type="file" multiple/>
const inputFiles = document.getElementById("file-input");
const files = [];
for (let i = 0; i < inputFiles.length; i++) {
files[i] = { file: inputFiles[i] };
}
const task = UC.upload({
files: files,
providerId: "<YOUR_PROVIDER_ID>",
throwUploadError: false, // Prevent upload errors
});
try {
const uploaded = await task.start();
const uploadedFile = uploaded[0];
// Check if the file uploaded successfully
if (uploadedFile.responseCode === 200) {
// File uploaded successfully
console.log(uploadedFile.key); // Uploaded path
console.log(uploadedFile.file); // Uploaded file
}
else {
// File failed to upload
console.log(uploadedFile.errorCode);
}
}
catch (e) {
// Errors not related to the HTTP upload request will need to be caught
console.log(e.code); // Error code
console.log(e.message); // Error message
}
}