1

I have a simple use case as below -

User triggers a REST API call to process file upload

The file gets uploaded on cloud at back end

The API returns a response with URL for downloading the file like - http://somedomain/fileName.zip

After file gets downloaded at Client side , there is another API call to update DOWNLOAD count in database for the downloaded file

This is being achieved using Angular code at client side .

The pseudo code for this is as below :

//Download Service Call to Download File . It returns Obseravable 
downloadService.downloadFile.subscribe(

(data: downloadData) => processDataDownload(data);
(err) => this.message = "Error Downloading File ";

);
//method processing file download and updating download count 
private processDataDownload(data : Response){

   this.downloadFile(data);
   this.updateDownloadCount(data);

}

//download a file using URL 
private downloadFile(data : Response) : void {
   //standard java script code to get file download using URL click     
    var a = document.createElement("a");
    a.href = data.downloadUrl;
    fileName = data.downloadUrl.split("/").pop();
    a.download = fileName;
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
    a.remove();
}
//update download count 
private updateDownloadCount(data : Response ){
    //another http call to update download count for files 
}

Now , my question is :

1)Is there any way we can make updateDownloadCount method gets called ONLY after the file gets DOWNLOADED successfully ?

2)Meaning , the java script code in method - downloadFile , triggers a file download using programmatic URL click

3)Can we wait for this download happen and then call updateDownloadCount ?

4)Can we wait for DOWNLOAD event completion and then trigger database update ?

5)Is there any way we can achieve this ?

Atul
  • 1,560
  • 5
  • 30
  • 75
  • 1
    check this out: https://stackoverflow.com/questions/1106377/detect-when-browser-receives-file-download – Shail_bee Oct 22 '19 at 18:06

1 Answers1

1

I'm assuming downloadService.downloadFile isn't actually downloading the file, so much as it's downloading the file details, correct? When you create a download url as you are doing in your sample, you are essentially telling the browser to handle the download process. If you want your application to handle it, you'll need to take a slightly different approach.

You basically want to use Angular's HttpClient to grab the file blob from the server. You can use it to track progress. When it's completed, you can send the confirmation to the API and render the internal download link.

Something like:

downloadFile(file) {
  return this.http.get(
    this.baseUrl + 'file.url', 
    {         
        responseType: 'blob',
        reportProgress: true,
        observe: 'events',          
    }
  );
}

In your component you can subscribe to this download and check result.type against HttpEventType.DownloadProgress for progress or HttpEventType.Response for download completion.

this.service.downloadFile(myfile).subscribe(result => {
    if (result.type === HttpEventType.DownloadProgress) {
      ...calc percent
    }
    if (result.type === HttpEventType.Response) {
      ... this is where you create the blob download link and call your api
    }
});
John Gallego
  • 641
  • 7
  • 10
  • Yes John . That is one of the option . But we have the restriction that no additional Http Call needs to be made here. The reason API is returning a URL is actually to avoid going to server and download data as a blob. Can we do anything WITHOUT making additional Http Call ? – Atul Oct 23 '19 at 06:26
  • Unless I'm missing something, your current implementation is making three HTTP requests. First, you are calling your API to give you the download details, after which you are creating a download link on the DOM. When the user clicks, that's another HTTP request to download the file. (though obviously this doesn't happen as you want it to happen). It's the same with the implementation I suggested. The only difference is that you are handling the download request by leveraging HTTP Client's oberve capabilities. Either way the download HTTP call needs to happen. – John Gallego Nov 04 '19 at 18:44