Practice: Using JSZip to Download Multiple Remote Images


Using JSZipUtils.getBinaryContent
JSZipUtils provides getBinaryContent to fetch a file from remote server like below:
// loading a file and add it in a zip file
JSZipUtils.getBinaryContent("path/to/picture.png", function (err, data) {
   if(err) {
      throw err; // or handle the error
   }
   var zip = new JSZip();
   zip.file("picture.png", data, {binary:true});
});
Using JQuery Deferred Pattern to Wait all Ajax Request Finished
We will loop all image urls, and call getBinaryContent to add the remote image into the dest zip file. But getBinaryContent is an async call, it will return immediately. We have to wait until al ajax request fished: either succeeded or failed.

We can use JQuery Deferred pattern

When loop al image urls, we will call addToZip: it calls JSZipUtils.getBinaryContent and return a Deferred object, which will be set as resolved when the ajax request finished. 
We put all Deferred objects into an array, then use jQuery.when().done(generateZip) to execute the callback generateZip when all ajax requests finished.
The generateZip will generate the zip and call saveAs in FileSaver.js.
The Complete Code
<script src='//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'/>
<script src='/js/jszip/jszip.min.js'/>
<script src='/js/jszip/jszip-utils.min.js'/>
<script src='/js/jszip/FileSaver.js'/>
<script>
function downloadAllImages(imgLinks){
 var zip = new JSZip();
 var deferreds = [];
 for(var i=0; i<imgLinks.length; i++)
 {
  deferreds.push( addToZip(zip, imgLinks[i], i) );
 }
 $.when.apply(window, deferreds).done(generateZip);
}
function generateZip(zip)
{
 var content = zip.generate({type:"blob"});
 // see FileSaver.js
 saveAs(content, "downloadImages.zip");
}
function addToZip(zip, imgLink, i) {
  var deferred = $.Deferred();
  JSZipUtils.getBinaryContent(imgLink, function (err, data) {
    if(err) {
      alert("Problem happened when download img: " + imgLink);
      console.erro("Problem happened when download img: " + imgLink);
      deferred.resolve(zip); // ignore this error: just logging
      // deferred.reject(zip); // or we may fail the download
    } else {
      zip.file("picture"+i+".jpg", data, {binary:true});
      deferred.resolve(zip);
    }
 });
return deferred;
}
</script>
Resources
jQuery.Deferred is the most important client-side tool you have
Understanding JQuery.Deferred and Promise
How to use JSZip
JSZipUtils.getBinaryContent

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)