Added fetchAndDownloadFile method to utils service

The existing approach didn't expose when the download was complete.

By fetching the file upfront and downloading from a blob we can better
estimate when the download is complete because we load the file in
memory, and then download from there.

The promise resolves after the file is in memory, so the delay between
the promise resolving and the file actually being downloaded is a lot
shorter, and based on the size of the file.
This commit is contained in:
Fabien "egg" O'Carroll 2023-04-07 12:52:37 +07:00
parent aa5272ffb9
commit 3dac3cb4e2

View File

@ -1,4 +1,5 @@
import Service from '@ember/service';
import fetch from 'fetch';
export default class UtilsService extends Service {
downloadFile(url) {
@ -14,6 +15,29 @@ export default class UtilsService extends Service {
iframe.setAttribute('src', url);
}
/**
* This method will fetch a file from the server and then download it, resolving
* once the initial fetch is complete, allowing it to be used with loading spinners.
*
* @param {string} url - The URL of the file to download
* @returns {Promise<void>}
*/
async fetchAndDownloadFile(url) {
const response = await fetch(url);
const blob = await response.blob();
const anchor = document.createElement('a');
anchor.href = window.URL.createObjectURL(blob);
anchor.download = /filename="(.*)"/.exec(response.headers.get('Content-Disposition'))[1];
document.body.append(anchor);
anchor.click();
document.body.removeChild(anchor);
}
/**
* Remove tracking parameters from a URL
* @param {string} url