0

I am trying to download files from some website say 'website.com'. I have all the unique ids in an array.

This is the code that I have written:

for(var i=0;i<ids.length;i++) {
    var timeInterval = 1000;
    (function(i,timeInterval){
        setTimeout(function(){
            var link = document.createElement('a');
            link.href= "http://website.com/download/"+ids[i];
            var e = document.createEvent('MouseEvents');
            e.initEvent('click', true, true);
            link.dispatchEvent(e);
            console.log(ids[i]);
            console.log(timeInterval);
        }, timeInterval);
        timeInterval = (i+1)*1000;
    })(i,timeInterval);
}

Problem with this is that it downloads the file corresponding to the last element of the array ids, not all of them.
How can I make the loop work for each and every element in ids?
PS: I have tried out various solutions given in different related questions, but none could bring desired results, so I had to post it as a different question.

Sahil
  • 315
  • 5
  • 21
  • 2
    You're simulating a click on a link. Clicking on a link reloads the page and stops the script from running. – Barmar Sep 09 '14 at 21:54
  • I'm surprised the browser allows you to initiate downloads like this. I thought it was prohibited because a website could use it to trigger hundreds of downloads. – Barmar Sep 09 '14 at 21:59
  • @Barmar: chrome makes you confirm that you want more files after the 2nd or 3rd one downloads. – dandavis Sep 09 '14 at 22:56

1 Answers1

3

You're updating the "timeInterval" parameter at the end of the anonymous function, and while there's nothing wrong with that statement it doesn't do any good — it updates the "timeInterval" parameter, not the "timeInterval" variable outside the loop. You could do this as one alternative:

for(var i=0;i<ids.length;i++) {
    var timeInterval = (i + 1) * 1000;
    (function(i,timeInterval){
        setTimeout(function(){
            var link = document.createElement('a');
            link.href= "http://website.com/download/"+ids[i];
            var e = document.createEvent('MouseEvents');
            e.initEvent('click', true, true);
            link.dispatchEvent(e);
            console.log(ids[i]);
            console.log(timeInterval);
        }, timeInterval);
    })(i,timeInterval);
}

to just do the computation outside the anonymous function.

edit — note that you may still run into problems, depending on the context in which this code runs. Browsers might not like this behavior.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 1
    I think he'll still run into the problem I mentioned in my comment. The only difference is that it will load the first link instead of the last. – Barmar Sep 09 '14 at 21:55
  • 1
    @Barmar well if those links are things that return attachments (like, files to download), then it'd work. – Pointy Sep 09 '14 at 21:57
  • If the link downloads files, it won't reload the page, will it? – Ruan Mendes Sep 09 '14 at 21:57
  • But, why won't downloads work this way? I didn't get it. Is there anything that I can do? – Sahil Sep 09 '14 at 23:03
  • The OP could also adjust the time interval passed to *setTimeout*: `...}, timeInterval * i);`. – RobG Sep 09 '14 at 23:19
  • @RobG yes there are lots of ways of doing it. The anonymous function could do it and return the next-iteration value too. – Pointy Sep 09 '14 at 23:20
  • @JuanMendes—whether a browser downloads a file or displays it depends on things like MIME type and browser settings. I don't think it's possible to **guarantee** that a browser will download a file rather than display it (e.g. it may unpack a ZIP file and display the content). Not long ago, PDFs were mostly downloaded by default, now they're mostly displayed by default. – RobG Sep 09 '14 at 23:31
  • @RobG I was just saying the OP already knows they are going to download. However, if the server sends the Content-Disposition headeras attachment, as far as I know, the browser will download the file. http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1 What cannot be guaranteed (and depends on browser, configuration and MIME type) is that setting content disposition to inline will actually display it inline, for example, a zip file. See http://stackoverflow.com/questions/1395151/content-dispositionwhat-are-the-differences-between-inline-and-attachment – Ruan Mendes Sep 10 '14 at 12:31