8

I am using Angular js to show loading screen. It works for all the REST services call except REST service to download the file. I understand why it is not working because for download I am not making any service call using $resource; instead of that I am using normal approach to download the file therefore Angular js code doesn't have any control on start/finish the service request. I tried to use $resource to hit this REST service however I am getting the data from this service and in this case loading screen was working fine however not sure how to use this data to display to user to download in angular way. Following are required details. Please help.

Approach 1 using iframe approach:

 /*Download file */
            scope.downloadFile = function (fileId) {
                //Show loading screen. (Somehow it is not working)
                scope.loadingProjectFiles=true;
                var fileDownloadURL = "/api/files/" + fileId + "/download";
                downloadURL(fileDownloadURL);
              //Hide loading screen
                scope.loadingProjectFiles=false;
            };

            var $idown;  // Keep it outside of the function, so it's initialized once.
            var downloadURL = function (url) {
                if ($idown) {
                    $idown.attr('src', url);
                } else {
                    $idown = $('<iframe>', { id: 'idown', src: url }).hide().appendTo('body');
                }
            };

Approach 2 using $resource (Not sure how to display data on screen to download)

/*Download file */
            scope.downloadFile = function (fileId) {
                //Show loading screen (Here loading screen works).  
                scope.loadingProjectFiles=true;                 
                  //File download object
                    var fileDownloadObj = new DownloadFile();
                 //Make server call to create new File
                    fileDownloadObj.$get({ fileid: fileid }, function (response) {
                        //Q? How to use the response data to display on UI as download popup
                        //Hide loading screen
                        scope.loadingProjectFiles=false;
                    });

            };
Peter Butkovic
  • 11,143
  • 10
  • 57
  • 81
joy
  • 3,669
  • 7
  • 38
  • 73
  • This is basically how I am doing it too, +1 for question. – Strawberry Sep 30 '13 at 16:54
  • hey Strawberry...are you also facing any problem? Which approach you are taking first or second? – joy Sep 30 '13 at 17:04
  • In approach 1, if you remove `scope.loadingProjectFiles = false`, will loading screen show up? – Ye Liu Sep 30 '13 at 17:07
  • @DilipKumar I actually misread the question. So you're trying to download a file ti display to a user correct? You said you were able to retrieve the data, but you're not seeing it in the response? Is that the issue here? – Strawberry Sep 30 '13 at 17:20
  • When i removed scope.loadingProjectFiles = false then i am getting loading screen however after file download it is not going away. – joy Sep 30 '13 at 17:22
  • @Strawberry...in approach2 i am able to get the data as well loading screen works however in this approach i am not sure how to open popup to download file. In approach 1 i am not getting loading screen. – joy Sep 30 '13 at 18:19
  • @DilipKumar That is no surprise to you, isn't it? Approach 1 isn't working because you set `loadingProjectFiles = false` too soon! You need to find a way to delay it. Take a look at this question, it might help http://stackoverflow.com/questions/1106377/detect-when-browser-receives-file-download – Ye Liu Sep 30 '13 at 18:41
  • Great question. Looking for the same thing. Anyone find a solution yet? – lostintranslation Nov 11 '13 at 14:51
  • At least i am not :-) – joy Nov 24 '13 at 01:57
  • @joy Good question, did you find a solution to it? – huan feng Oct 21 '15 at 05:56
  • not yet...i moved to other work and couldn't spend time more to explore other solution. – joy Nov 15 '15 at 19:21

2 Answers2

1

This is the correct pattern with the $resource service:

scope.downloadFile = function (fileId) {
    //Show loading screen (Here loading screen works).  
    scope.loadingProjectFiles=true;                 
    var FileResource = $resource('/api/files/:idParam', {idParam:'@id'});
    //Make server call to retrieve a file
    var yourFile = FileResource.$get({ id: fileId }, function () {
        //Now (inside this callback) the response data is loaded inside the yourFile variable
        //I know it's an ugly pattern but that's what $resource is about...
        DoSomethingWithYourFile(yourFile);
        //Hide loading screen
        scope.loadingProjectFiles=false;
    });
 };

I agree with you that this is a weird pattern and is different of other APIs where the downloaded data is assigned to a parameter in a callback function, hence your confusion.

Pay attention to the names and the cases of the parameters, and look that there're two mappings involved here, one between the caller to the $resource object and the object itself, and another between this object and the url that it contructs for downloading the actual data.

Vi100
  • 4,080
  • 1
  • 27
  • 42
0

Here are some idea's for the second approach, you could present the user with a link after the download has happened:

Community
  • 1
  • 1
Pieter Herroelen
  • 5,977
  • 2
  • 29
  • 37