mottosson
mottosson

Reputation: 3763

JSZip and Async.each -> not assignable to parameter of type 'JSZipObject[]'

I'm building an Angular 2 CLI app with Typescript where I'm parsing a zip file with text documents, using JSZip library. The code below works, but I get some errors from typescript:

Argument of type '{ [key: string]: JSZipObject; }' is not assignable to parameter of type 'JSZipObject[]'.

Property 'find' is missing in type '{ [key: string]: JSZipObject; }'.

fileChangeEvent(fileInput){
  let files = fileInput.target.files[0];
  let zip = new JSZip();
  let files = [];

  zip.loadAsync(files)
    .then(zip => {
    async.each(zip.files, function(zipItem, callback) {
      zipItem
        .async('string')
        .then((content) => {

        files.push(content);
        
        callback(null);
      });
    }, function(err) {
      if( err ) {
        console.log('A file failed to process');
      } else {
        console.log('All files have been processed successfully');
        // do something with parsed files array
      }
    });
  });
}

There seems to be a problem passing zip.files to async.each.

As I said, it works just using ng serve, but the project can't be built unless I get rid of the errors.

Anyone knows why I get them?

Can I do the same thing with promises/generators/whatever and skip async.each?

Upvotes: 2

Views: 637

Answers (1)

Jasperan
Jasperan

Reputation: 3688

In order to convert a JSZipObject into a File object, you need to convert the JSZipObject to a Blob and then to a File.

As an example, this function unzips and returns txt files as a File array

const unzipTxtFiles = async (zipFile: File) => {
  const zip = new JSZip();
  const arrayBuffer = await zipFile.arrayBuffer();
  const contents = await zip.loadAsync(arrayBuffer);

  const files: File[] = [];
  const filePromises = Object.values(contents.files).map(async (file) => {
    if (!file.dir && file.name.endsWith(".txt")) {
      const content = await file.async('blob'); // <-- Conversion code starts here
      const newFile = new File([content], file.name);
      files.push(newFile);
    }
  });

  await Promise.all(filePromises);
  return files;
};

Upvotes: 0

Related Questions