Utilizing JSZip with asynchronous dynamic imports

In my current Angular 18 project, I am utilizing JSZip to compress multiple .txt files into an archive. Initially, I used the conventional JSZip syntax as shown below:

import JSZip from "jszip";
export class ScriptDatabase {
  // My class code...

  exportDatabase(): Promise<Blob> {
    const zip = new JSZip();
    for (const [id, archive] of this.archives) {
      zip.file(`${id}.txt`, archive.exportArchive());
    }
    return zip.generateAsync({type: "blob"});
  }
}

To optimize my application's final bundle size and enhance its performance, I attempted to switch to dynamic async imports. My initial approach was:

  async exportDatabase(): Promise<Blob> {
    const JSZip = await import('jszip');
    const zip = new JSZip();
    for (const [id, archive] of this.archives) {
      zip.file(`${id}.txt`, archive.exportArchive());
    }
    return await zip.generateAsync({ type: "blob" });
  }

However, I encountered a roadblock when I realized that the JSZip constant was not a constructor, preventing me from calling new. This led me to manipulate JSZip differently as an instance:

  async exportDatabase(): Promise<Blob> {
    const JSZip = await import('jszip');
    for (const [id, archive] of this.archives) {
      JSZip.file(`${id}.txt`, archive.exportArchive());
    }
    return await JSZip.generateAsync({ type: "blob" });
  }

Despite my IDE no longer showing errors and the app successfully building, executing the method resulted in an error:

ERROR TypeError: JSZip.file is not a function
.

Upon logging the object, it became evident that I had obtained an incomplete version of the JSZip object, only allowing the use of loadAsync. It's clear that my implementation was incorrect.

At this point, I am puzzled. What would be the proper syntax for incorporating JSZip with dynamic imports?

Answer №1

If you want to dynamically import scripts into your angular application, follow the steps below.

Start by configuring the root script that needs to be moved to the assets folder for dynamic importing.

     ...
     "options": {
        "assets": [
          {
            "glob": "**/*",
            "input": "./node_modules/jszip/dist",
            "output": "."
          }
        ],
        ...

Next, you can create a script tag programmatically and define the logic to execute when the script loads.

ngOnInit() {
  const script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = 'jszip.min.js';
  script.onload = () => {
    const zip = new (window as any).JSZip();

    zip.file('Hello.txt', 'Hello World\n');

    const img: any = zip.folder('images');
    // img.file('smile.gif', imgData, { base64: true });

    zip.generateAsync({ type: 'blob' }).then(function (content: any) {
      // see FileSaver.js
      console.log(content);
      // saveAs(content, 'example.zip');
    });
  };
  document.head.appendChild(script);
}

Check out the Stackblitz Demo here!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

problem with Angular routing on a component within a module loaded lazily

I am encountering an issue with routing the child of lazy loaded modules. It redirects on click but on refresh, it gives an error message saying abc/runtime.js Although it redirects successfully, upon refreshing the page, I encounter this error: GET htt ...

Unable to install the most recent version of Angular CLI

As I embarked on a new project using Angular, it became clear that I needed to update my global packages. Running Windows10, the ng -v command displayed the following: Angular CLI: 6.0.8 Node: 8.12.0 OS: win32 x64 Upon further investigation, I discovere ...

Tips for importing a PDF file and storing it in your database

I have a project using Angular 7, .NET Framework, and MongoDB where I am creating user profiles. One of the requirements is to allow users to optionally upload a PDF file along with their other information. This is what I have implemented so far: <labe ...

Generate a new entity by merging two objects containing keys that are identified by dots

I have a unique input as shown below: { survey.subObject1.key1: true, survey.subObject1.key2: "OTHER", survey.subObject2.key3: "[1,2]", survey.subObject2.key4: false, survey2.subObject3.key5: false, survey2.subObject3.key6: false } I a ...

Utilizing Typescript with Vue 3's Injection Feature

Using the new Vue 3 Composition API, I have created a "store" for reactive data. const state = reactive<State>({ accessToken: undefined, user: undefined, }); export default { state: readonly(state), } When my app is created, I pass the store ...

Launch a TypeScript Node.js server on Heroku deployment platform

I'm having trouble deploying a Node.js server built with TypeScript on Heroku. Despite following various tutorials and searching through Stack Overflow for solutions, I can't seem to make it work. Here is the code I have in my tsconfig.json and p ...

The React state remains stagnant and does not receive any updates

Although there have been numerous questions on this topic before, each one seems to be unique and I haven't found a close match to my specific issue. In my scenario, I have a grid containing draggable ItemComponents. When an item is selected, additio ...

Deciphering the Mysteries of API Gateway Caching

It seems like a common pattern to enable an API Gateway to serve an Angular Webapp by pulling it from S3. The setup involves having the API gateway with a GET request set up at the / route to pull index.html from the appropriate location in the S3 bucket, ...

Tips for configuring owl-carousel-o to display each image in fullscreen mode in angular8

I've incorporated the ngx-owl-carousel-o library to make owl carousel work seamlessly with angular8: https://www.npmjs.com/package/ngx-owl-carousel-o To implement it, I followed a helpful guide: The challenge now is that I want each 'owl-item& ...

Deactivate the Mention and Hash tag in ngx-linkifyjs

I am currently utilizing ngx-linkifyjs to automatically convert URLs in text to clickable hyperlinks. However, I am facing an issue where it is also converting # and @ tags into links. Is there a way to prevent the conversion of # and @ while maintain ...

Displaying an array in HTML where one parameter serves as the key is a common task that

{ "Id": "12345", "length": [ { "review": { "1": { "request": [ { "days" ...

Leveraging the power of react-hook-form in combination with the latest version 6 of @mui

When using MUI v5 date pickers, I utilized the following method to register the input with react-hook-form: <DatePicker ...date picker props renderInput={(params) => { return ( <TextField {...params} ...

Activate the field once the input for the other field is completed

I have a form where the last name field is initially disabled. How can I make it so that the last name field becomes enabled only when the first name is inputted? <form> <label for="fname">First name:</label><br> ...

An error occurred suddenly while building: ReferenceError - the term "exports" is not defined in the ES module scope

Having trouble resolving this error in the Qwik framework while building a static site: ReferenceError: exports is not defined in ES module scope at file:///media/oem/MyFiles/8_DEVELOPMENT/nexasoft/server/@qwik-city-plan.mjs:1:1097 at ModuleJob. ...

Frequently pinging a health check endpoint using Angular

I am currently learning Angular and attempting to create a health check connection to monitor the availability of my backend in the background. This check will be executed every 5 seconds to ensure that a status of 200 OK is received: Below is the code fo ...

The conversion of a newline in an Angular page is done using &lt;br/&gt tag

Here is a function I have: setLocalVariableOnAccepted(ogp, hb, responseJson) { if (responseJson.ofgp === undefined) { this.ogpStatus = 'orange'; this.ogpStatusMsg = responseJson.ofgp + ', <br/> No change. Previous va ...

Utilizing Svelte to Retrieve User Input through Store Functions

Exploring the capabilities of Svelte as a newcomer, I am attempting something that may or may not be achievable, but I remain optimistic! ...

Is there any shorthand method for passing a child as a template with a reference to a component in Angular versions 2 and above

I am currently exploring ways to reduce the clutter when passing templates to angular components. Take a look at the code snippet below: <parent> <ng-template #child1><div>Test</div></ng-template> <ng-template #child2 ...

Developing a login feature in Angular 2 using Spring Security

I am currently in the process of integrating Spring Security with a custom Angular 2 login. Specifically, I have set up an endpoint in my application that is protected by Spring Security. If someone tries to access this endpoint, they will be redirected to ...

Is it possible to utilize the `__init__` method to import files from the parent directory into a subfolder?

Imagine having a directory structure like this dir_one/ main.py __init__.py dir_two/ sub.py __init__.py In the current setup, both of the init.py files are empty. In the sub.py file within dir_two, an attempt is made to import ...