Well, I’m not sure how helpful this is, but since I wasn’t able to get your stackblitz into a format suitable for playing around with, I made a scratch app that does seem to work, in that the downloaded zip files seem to be uncorrupted. Haven’t tested it extensively, but see if you can adapt it to your situation. Now that I know what zip library you’re using, we can take advantage of the fact that it accepts Promise
s in the file
method, making things a bit simpler.
home.page.html
<ion-content>
<ion-list>
<ion-item *ngFor="let fc of fcs">
<ion-input [formControl]="fc"></ion-input>
</ion-item>
</ion-list>
<ion-button (click)="addRaw()">add</ion-button>
<ion-button (click)="doZip()">zip</ion-button>
<ion-button (click)="downloadZip()">download</ion-button>
</ion-content>
home.page.ts
export class HomePage {
fcs: FormControl[] = [];
zipped: ArrayBuffer | null = null;
constructor() {
}
addRaw(): void {
this.fcs.push(new FormControl());
}
b64ify(raw: string): Promise<string> {
return Promise.resolve(btoa(raw));
}
b64ifyAll(): Promise<string>[] {
return this.fcs.map(fc => this.b64ify(fc.value));
}
doZip(): void {
let b64ps = this.b64ifyAll();
let zipper = new JSZip();
for (let i = 0; i < b64ps.length; ++i) {
zipper = zipper.file(`${i}.txt`, b64ps[i], {base64: true});
}
zipper.generateAsync({type: "arraybuffer"}).then(zar => {
this.zipped = zar;
});
}
downloadZip(): void {
let filename = "scratch.zip";
let blob = new Blob([this.zipped!], {type: "application/zip"});
let url = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.setAttribute('href', url);
a.setAttribute('download', filename);
a.style.display = 'none';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
}
It’s pretty bare-bones, but I think incorporates all of the core aspects of your problem. Click “add” as many times as needed to provide new text input areas to type stuff into, type stuff into them, click “zip” to do the zipping, and then “download” to download the resultant zip file. Promise.resolve(b2a(raw))
uses the internal JavaScript base64er and Promise
-ifies it to make sure it would work with any other asynchronous source. We don’t need Promise.all
any more, because we’re feeding JSZip each Promise
instead of resolving them in app code.