Currently, I download byte arrays as files using JsInterop.
Here is my JS file:
function downloadFile(fileName, base64String) {
const url = "data:application/octet-stream;base64," + base64String;
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
}
And here is a method in my razor component:
async Task DownloadFile(byte[] file)
{
ShowMessage("Start");
await JSRuntime.InvokeVoidAsync("downloadFile", "FileName", Convert.ToBase64String(file));
ShowMessage("End");
}
This code works, and I am able to download files. My issue is that I cannot implement the progress bar, or even show the loading spinner because await JSRuntime
has no idea about an actual file download size and its progress. JSRuntime only launches the process of downloading and immediately continues to the next line of code.
In the code above ShowMessage("Start") and ShowMessage("End") are both shown one after another as soon as I click the download button, but the file in the browser downloads much later (depending on the file size).
How may I await the download process and execute relevant code only when the file has been downloaded? And it would be even better if I could read downloaded bytes to show a progress bar with percentages.
Update: for test purposes, I upload the file from the browser and store it in a byte[] variable. Then I download the same file from the variable using JS. Even though I store the file in the memory, it still takes time to download the file. I suppose that when I store a file in memory, it is already on my PC (client), and should download immediately. But instead, my window gets frozen for the duration of downloading the file. Tested on 6 - 11- 20 MB files. The bigger file, the more I have to wait for it to download.
I suggest you should be show message ShowMessage("Start") and ShowMessage("End"); in function downloadFile at JS