Events
Events are the heartbeat of a Resumable.js integration. Every meaningful state change — a file added, a chunk acknowledged, an error returned, the entire queue finishing — fires an event you can listen to. Understanding the event lifecycle isn't optional; it's how you build progress bars, error recovery flows, analytics hooks, and every other piece of upload UX. This reference covers every event with its callback signature, timing, and practical usage. For the full API surface, see the API hub.
Listening to Events
Bind handlers using the .on() method:
r.on('eventName', function (/* arguments */) {
// handle it
});
Multiple handlers can be bound to the same event. They fire in the order they were registered.
File Lifecycle Events
fileAdded
r.on('fileAdded', function (file, event) { });
| Parameter | Type | Description |
|---|---|---|
file | ResumableFile | The file object that was added. |
event | Event | The original DOM event (from input change or drop). |
Fires when a single file passes validation and enters the queue. This is the place to update your file list UI, display the file name and size, and optionally call r.upload() to start immediately. If you want to gate uploads behind a "Start" button, skip the auto-upload and let the user trigger it.
Returning false from this handler prevents the file from being added. Use this for custom validation logic beyond what fileType and maxFileSize cover:
r.on('fileAdded', function (file, event) {
if (file.fileName.startsWith('.')) {
alert('Hidden files are not allowed.');
return false;
}
});
filesAdded
r.on('filesAdded', function (arrayOfFiles, event) { });
| Parameter | Type | Description |
|---|---|---|
arrayOfFiles | ResumableFile[] | All files added in this batch. |
event | Event | The original DOM event. |
Fires once per user action, after all individual fileAdded events. If a user selects five files in the picker, fileAdded fires five times, then filesAdded fires once with all five. Use this for batch-level logic: "5 files queued, 23 MB total — click Upload to begin."
fileSuccess
r.on('fileSuccess', function (file, message) { });
| Parameter | Type | Description |
|---|---|---|
file | ResumableFile | The file that completed. |
message | string | The response body from the server for the final chunk. |
Fires when every chunk of a file has been uploaded and acknowledged. The message parameter contains the server's response to the last chunk — handy for receiving a file ID, CDN URL, or processing status back from your backend.
r.on('fileSuccess', function (file, message) {
var response = JSON.parse(message);
showThumbnail(file.fileName, response.thumbnailUrl);
});
fileError
r.on('fileError', function (file, message) { });
| Parameter | Type | Description |
|---|---|---|
file | ResumableFile | The file that failed. |
message | string | The error message or server response body. |
Fires when a chunk fails after exhausting all retries (controlled by maxChunkRetries). This is your cue to show an error state, offer a retry button, or log the failure. The message often contains the HTTP response body, so parse it for server-side error details.
r.on('fileError', function (file, message) {
console.error(file.fileName + ' failed:', message);
appendRetryButton(file);
});
fileRetry
r.on('fileRetry', function (file) { });
| Parameter | Type | Description |
|---|---|---|
file | ResumableFile | The file being retried. |
Fires when a chunk retry is initiated (before the retry request is sent). Use this for logging or to show a "retrying…" indicator. This event fires for each retry attempt, so if maxChunkRetries is 3, you could see up to 3 fileRetry events per failed chunk.
fileProgress
r.on('fileProgress', function (file, message) { });
| Parameter | Type | Description |
|---|---|---|
file | ResumableFile | The file whose progress changed. |
message | string | The server response for the completed chunk. |
Fires when a chunk is successfully uploaded, updating the file's progress value. Call file.progress() inside this handler to get the current value (0 to 1). Frequency is governed by throttleProgressCallbacks — if set to 0.5, you'll get at most two updates per second regardless of how fast chunks complete.
r.on('fileProgress', function (file) {
var pct = Math.round(file.progress() * 100);
updateProgressBar(file.uniqueIdentifier, pct);
});
Queue-Level Events
uploadStart
r.on('uploadStart', function () { });
Fires when upload() is called and at least one file begins transferring. No parameters. Good for showing a global "uploading…" spinner or disabling form inputs.
complete
r.on('complete', function () { });
Fires when every file in the queue has finished uploading (all fileSuccess events have fired). No parameters. This is the "all done" signal — trigger post-upload workflows, show a success banner, or redirect the user.
r.on('complete', function () {
document.getElementById('status').textContent = 'All uploads complete.';
enableSubmitButton();
});
progress
r.on('progress', function () { });
Fires whenever overall queue progress changes. No parameters — call r.progress() inside the handler to get the aggregate value (0 to 1). Use this for a global progress bar that spans all files.
r.on('progress', function () {
var pct = Math.round(r.progress() * 100);
document.getElementById('global-bar').style.width = pct + '%';
});
error
r.on('error', function (message, file) { });
| Parameter | Type | Description |
|---|---|---|
message | string | The error message or server response. |
file | ResumableFile | The file associated with the error. |
A general error event. Fires alongside fileError but provides a centralized hook for logging, analytics, or global error banners. If you're already handling errors in fileError, you may not need this — but it's useful for catch-all telemetry.
pause
r.on('pause', function () { });
Fires when pause() is called. No parameters. Use it to update UI state — swap a "Pause" button label to "Resume," for instance.
cancel
r.on('cancel', function () { });
Fires when cancel() is called on the Resumable instance. No parameters. All files have been removed from the queue at this point. Reset your UI to its initial state.
beforeCancel
r.on('beforeCancel', function () { });
Fires just before cancellation proceeds. Returning false from this handler prevents the cancel. Use it for confirmation dialogs:
r.on('beforeCancel', function () {
return confirm('Cancel all uploads?');
});
Chunking Events
These events relate to the file-reading (slicing) phase, before any network requests happen.
chunkingStart
r.on('chunkingStart', function (file) { });
Fires when Resumable.js begins reading/slicing a file into chunks. For small files this is nearly instantaneous; for multi-gigabyte files you may want to show a "preparing…" state.
chunkingProgress
r.on('chunkingProgress', function (file, ratio) { });
| Parameter | Type | Description |
|---|---|---|
file | ResumableFile | The file being chunked. |
ratio | number | Progress from 0 to 1. |
Fires during the chunking/reading phase. Useful for very large files where the slicing itself takes noticeable time.
chunkingComplete
r.on('chunkingComplete', function (file) { });
Fires when all chunks for a file have been prepared and are ready for upload.
catchAll
r.on('catchAll', function (eventName /* , ...args */) { });
A wildcard handler that fires for every event. The first argument is the event name as a string; remaining arguments match the specific event's signature. Invaluable for debugging — log everything during development, then remove it before shipping:
r.on('catchAll', function () {
console.log('Resumable event:', arguments[0], Array.prototype.slice.call(arguments, 1));
});
Event Ordering
When a file completes its last chunk, events fire in this order:
fileProgress(final progress update, now at 1.0)fileSuccess(file is done)progress(queue-level progress recalculated)complete(only if this was the last file in the queue)
Understanding this sequence prevents subtle bugs — like showing "all done" in a progress handler before fileSuccess has had a chance to update the file's status in your UI.
Practical Architecture
For complex applications, consider routing all Resumable events through a single dispatcher that normalizes them into your app's state management layer — whether that's Redux, Zustand, a Vue store, or a simple event bus. This keeps Resumable.js as a transport layer and your UI framework as the rendering layer, with a clean boundary between them.
var events = ['fileAdded', 'fileProgress', 'fileSuccess', 'fileError', 'complete', 'pause'];
events.forEach(function (evt) {
r.on(evt, function () {
store.dispatch({
type: 'UPLOAD_' + evt.toUpperCase(),
payload: Array.prototype.slice.call(arguments)
});
});
});
That's every event Resumable.js emits. Wire them up thoughtfully and your upload UI will feel rock-solid.
