Here's the documentation for Pizzip for those unfamiliar: https://github.com/open-xml-templating/pizzip/tree/master/documentation
Also, I'm using VueJS (2), ES6, TS
I am trying to download individual files with Axios and then put them into a zip file using Pizzip.
async getFile(mat: Material): Promise<any> {
try {
const file = await axios.get(mat.url, { responseType: 'arraybuffer' })
return file.data
} catch (error) {
console.log(error)
return {}
}
}
This is giving me the ArrayBuffer
correctly. Then I have the following:
async getZip() {
let zip = new pizzip()
this.materials.forEach(async mat => {
const record = await PortalService.getFile(mat)
console.log(record) // logs the ArrayBuffer
zip.file(mat.name, record)
})
let files = zip.generate({ type: 'blob' })
return saveAs(files, `${this.request.id}-files.zip`)
}
Pizzip docs said that the data
argument of zip.file()
can be of type ArrayBuffer
, but when I download the zip it's just an empty archive. I've tried using the optional options
parameter for zip.file()
, but nothing has worked. Thank you in advance.
The issue is probably to do with the async for-loop. The forEach
method does not support async loop functions; it will just execute each iteration without waiting for the previous to finish. So basically you're generating the zip file before any files had been added to it.
There are two ways you can handle this:
await Promise.all(this.materials.map(async mat => {
const record = await PortalService.getFile(mat)
zip.file(mat.name, record)
}))
for (const mat of this.materials) {
const record = await PortalService.getFile(mat)
zip.file(mat.name, record)
}