Skip to main content
Version: v8.0.0

Tracking Request Progress

For operations like file uploads or downloads, providing feedback on the request's progress is crucial for a good user experience. Hyper-fetch makes this easy with the onUploadProgress and onDownloadProgress callbacks available on the useFetch and useSubmit hooks. These callbacks provide detailed information that you can use to display progress bars, time remaining, and more.

What you'll learn
  1. How to track upload and download progress for requests.
  2. How to use the onUploadProgress and onDownloadProgress callbacks.
  3. What progress data is provided (percentage, time left, size left).
  4. How to build a progress bar component in React.

onUploadProgress and onDownloadProgress

The onUploadProgress and onDownloadProgress callbacks receive an object with progress (0-100), timeLeft (in ms), sizeLeft (in bytes), and more. You can use this to update your UI in real-time.

function ProgressBars() {
const [upload, setUpload] = React.useState({ progress: 0, timeLeft: 0, sizeLeft: 0 });
const [download, setDownload] = React.useState({ progress: 0, timeLeft: 0, sizeLeft: 0 });

// Setup upload request
const { submit: startUpload, submitting: isUploading, onUploadProgress } = useSubmit(postFile);
onUploadProgress((progressData) => {
setUpload(progressData);
});

// Setup download request
const { submit: startDownload, submitting: isDownloading, onDownloadProgress } = useSubmit(getFile);
onDownloadProgress((progressData) => {
setDownload(progressData);
});

return (
<div className="p-4 border rounded-md space-y-6">
<div>
<h3 className="text-lg font-semibold">File Upload</h3>
<p className="text-sm text-gray-600">
Progress: {upload.progress}% | Time Left: {(upload.timeLeft / 1000).toFixed(1)}s
</p>
<div className="w-full bg-gray-200 rounded-full h-2.5 mt-2">
<div className="bg-blue-600 h-2.5 rounded-full" style={{ width: `${upload.progress}%` }}></div>
</div>
<button
className="mt-2 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 disabled:bg-gray-400"
onClick={() => startUpload()}
disabled={isUploading}
>
{isUploading ? "Uploading..." : "Start Upload"}
</button>
</div>
<div>
<h3 className="text-lg font-semibold">File Download</h3>
<p className="text-sm text-gray-600">
Progress: {download.progress}% | Time Left: {(download.timeLeft / 1000).toFixed(1)}s
</p>
<div className="w-full bg-gray-200 rounded-full h-2.5 mt-2">
<div className="bg-green-600 h-2.5 rounded-full" style={{ width: `${download.progress}%` }}></div>
</div>
<button
className="mt-2 px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 disabled:bg-gray-400"
onClick={() => startDownload()}
disabled={isDownloading}
>
{isDownloading ? "Downloading..." : "Start Download"}
</button>
</div>
</div>
);
}

How It Works

  1. We set up two useSubmit hooks, one for uploading (postFile) and one for downloading (getFile).
  2. We get the onUploadProgress and onDownloadProgress callback setters from their respective hooks.
  3. We call them with our state setters (setUpload and setDownload). These will be called repeatedly by Hyper-fetch during the request with the latest progress information.
  4. The state is then used to render the width of the progress bar divs and display text information.
  5. Clicking the buttons triggers the respective submit functions (startUpload, startDownload) to initiate the requests.

This provides clear, real-time feedback to the user for long-running requests.


Congratulations!

You've learned how to track request progress with Hyper-fetch!

  • You can monitor both upload and download progress.
  • You know how to use onUploadProgress and onDownloadProgress to update your UI.
  • You can build interactive progress bars to improve user experience.