2

The anchor tag click automates the download. Are there events attached to anchor tags that I can listen on ?

downloadMyFile(){
    const link = document.createElement('a');
    link.setAttribute('href', 'abc.net/files/test.ino');
    link.setAttribute('download', `products.csv`);
    document.body.appendChild(link);
    link.click();
    link.remove();
}
  • No, there are not. I don't think there is any way to determine whether a download was completed, using client-side code. – CBroe Jun 30 '22 at 08:12
  • The best would probably be to ask the user for a file handle and stream your data there yourself. But browser support is still low and it requires some user interaction since IIRC there is no "default" location for this API. You might be able to hack something around with a ServiceWorker. https://github.com/jimmywarting/StreamSaver.js might help. – Kaiido Jul 01 '22 at 08:16

1 Answers1

1

You will not be able to be notified by the client when the download completes this way.

You have 2 possible solutions, which mostly depends on the size of the file.

Option 1: Use an ajax call instead, you can stream the whole file in memory and then make the browser download it to a file (which will be instant). This means you have full view on the different download events.

// Get the content somehow 
// and then make the browser download
window.location.href = window.URL.createObjectURL(content);

Option 2: Monitor it with the server. I'd suggest you add a UID to the request like:

link.setAttribute('href', 'abc.net/files/test.ino?uid='+myUID);

Have the server keep track of that request and store details with the UID, you can then have another route report the status of the request when provided the UID. The problem with this is that you'd have to poll every now and then to know if the download is finished.

Since we do not know exactly the use for your request it is hard to tell if there are other possibilities. But IMHO there is no real use for you to know if the file has completed downloading. I cannot figure out why you'd want that in the beggining. I see it is a CSV file, they usually are not that big and the download should be real quick... Unless it is because it takes a lot of time to start since it has to be generated before? In this case I suggest you see a popular question/answer I made a while back. How to display a loading animation while file is generated for download?

Edit: Since the file may be big and not fit in memory, you could write the file on disk using the FileSystem API. This way you will be able to pipe the stream coming from your request directly to the filesystem. Since a stream has a close event, you'll be able to know when it is all done.

Salketer
  • 14,263
  • 2
  • 30
  • 58
  • The file size can differ and it could be > 2 GB. Since browsers have limitation for blob size, I don't want to use window.URL.createObjectURL. – Gaurab Rana Jul 01 '22 at 05:31
  • I've editted to include a solution using FileSystem API, unfortunately it is not yet very available. See https://caniuse.com/filesystem – Salketer Jul 01 '22 at 07:37
  • "which will be instant" no it won't be. First, the user *may* be prompted to choose a place where to save the file. We have no way of knowing this will happen, nor when this will finish. Then, even if the data is in memory, writing to disk isn't instant. Sure with SSD it's so fast we can believe it is, but not everyone uses SSD and some users *may* even choose to save on a network disk. Once again, there is no way to know if such a thing happens, nor when the file is actually saved. Also, simply navigating to the blob: URL won't always trigger a download, a lot of types can be navigated to. – Kaiido Jul 01 '22 at 07:57
  • Yes you're right it won't be instant... I worded it wrong. I Meant, "In a lot of cases, it will be a lot faster" – Salketer Jul 01 '22 at 08:03
  • Also, one huge difference is that you will have to load the whole file in memory, while OP's solution will stream it from the server to the disk. If the file is more than 4GB you won't be able to load it in Chrome. – Kaiido Jul 01 '22 at 08:13
  • Yes, hence why I added another solution for bigger files. – Salketer Jul 01 '22 at 08:32