Ensure all promises are resolved inside of for loops before moving on to the next

Within my angular 11 component, I have a process that iterates through elements on a page and converts them from HTML to canvas to images, which are then appended to a form. The problem I am encountering is that the promise always resolves after the 'done' message is logged to the console. How can I ensure that all instances of the 'generateCanvasFromHtml' function complete before continuing with the script following the loops? Despite this sequencing issue, the functionality of the function itself works as intended.

generateImagesFromPlan(): void {
    this.imageGenerating = true;

    // Create an empty FormData object for the images to be submitted
    const formData = new FormData();

    // Retrieve all sections available on the plan
    const pdfSections = document.querySelectorAll('[data-pdfsection]');
    for (let section of pdfSections as NodeListOf<HTMLElement>) {
      const sectionNumber = section.dataset.pdfsection;
      console.log('sectionName', sectionNumber)
    
      const pdfComponents = section.querySelectorAll('[data-component]');
      console.log('pdfComponents', pdfComponents)
    
      for (let element of pdfComponents as NodeListOf<HTMLElement>) {
        const componentImageNumber = element.dataset.component;
        console.log('componentName', componentImageNumber)
      
        this.generateCanvasFromHtml(element).then(canvas => {
          canvas.toBlob((blob) => {
            formData.append(sectionNumber, blob, componentImageNumber + '.png');
            console.log('blob added');
          }, 'image/png');

        });
      }
    }

    for (let pair of formData.entries()) {
      console.log(pair[0] + ', ' + pair[1]);
    }
    console.log('done');
    this.imageGenerating = true;
  }

  generateCanvasFromHtml(elem: HTMLElement): Promise<HTMLCanvasElement> {
   
    const clone = elem.cloneNode(true);
   
    const targetWidth = 1200;
    const iframe = document.createElement('iframe');
    iframe.style.visibility = 'hidden';
    iframe.width = targetWidth + 'px';
    iframe.height = '0px';
    document.body.appendChild(iframe);
  
    const iframeDocument = iframe.contentDocument;
    iframeDocument.replaceChild(clone, iframeDocument.documentElement);

    const targetHeight = iframeDocument.documentElement.scrollHeight;
    iframe.height = targetHeight + 'px';
    console.log('targetHeight=' + targetHeight);
    
    document.body.removeChild(iframe);
    const options = {
      width: targetWidth,
      windowWidth: targetWidth,
      height: targetHeight
    };

    return html2canvas(elem, options);

  }

Answer №1

To handle multiple promises, you can use the Promise.all method.

The approach you should take is to create an array containing calls to the function generateCanvasFromHtml() based on items in the pdfComponents array, then pass this array to Promise.all.

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

What is the process for removing an item from a JSON file using an HTTP DELETE request in a Node.js environment?

Essentially, I have a JSON file containing user and group data and I need to delete a specific group from it. Below is a snippet of the JSON file named authdata.json: [{ "name": "Allan", "role": ["Group Admin", "Super Admin"], "group": ["Cool- ...

Resolving the error message "Default props must have construct or call signatures for 'Component' in Typescript"

I'm currently working on a function component called MyComponent and I'm facing an issue with setting a default prop for component. The goal is to have the root node render as a "span" if no value is provided. However, I am encountering the follo ...

What is the process of destructuring an array containing objects?

Examining this JSON structure: { "Person": { "UID": 78, "Name": "Brampage", "Surname": "Foo" }, "Notes": [ { "UID": 78, "DateTime": "2017-03-15T15:43:04.4072317", "Person": { ...

A guide on activating the button once a user chooses an option from the dropdown menu in Ionic

I'm currently developing an Ionic Ecommerce app where I display products with their sizes. However, I'm facing an issue - I want to restrict users from adding the product to the cart without selecting a size first, but I'm struggling to impl ...

Angular Universal app experiencing "JavaScript heap out of memory" error in Docker container following several days of operation

I recently converted my Angular application to Angular Universal. It's built on Angular 15 and is running in a Docker container. I start the server using the command "npm serve:ssr". Everything works fine for a day or two, but then it starts throwing ...

Is there a way to customize the active width of ngx-tooltip specifically for an edge or link?

For my project, I am trying to incorporate a ngx-tooltip on the connection between two nodes. The tooltip is functioning well for both nodes and edges, but the edge size is smaller, requiring precise mouse positioning to trigger the tooltip. <ng-temp ...

Furnish an item for a particular service

I am currently attempting to utilize a service created by another individual (github). This particular service requires a configuration to be passed to it. As stated in the repository: To configure Neo4jSettings in your bootstrap: provide('Neo4jSet ...

Remove and input the data

Hello, I am currently working on a table where I need to delete specific data entries in columns labeled P(number) and tituloP(number). If the user chooses to delete the last P(number), it is a straightforward process. However, if they choose to delete a m ...

Is there a way to extract the current view date information from fullcalendar using Angular?

When working with HTML code... <full-calendar defaultView="dayGridMonth" [plugins]="calendarPlugins" #calendar></fullcalendar> I am wondering how to extract the date information from the #calendar element. I attempted to consult the fullcal ...

Issue with npm resolution due to package requiring another third-party dependency

I'm encountering an issue with a requirement and I'm hoping for some assistance. I currently have a package called @unicoderns/orm that relies on mysql, which can be found at https://github.com/unicoderns/ORM Now I'm working on developing ...

The error message "@graphql-eslint/eslint-plugin: problem with the "parserOptions.schema" configuration"

Our team is currently working on developing micro-services using NestJS with Typescript. Each of these services exposes a GraphQL schema, and to combine them into a single graph, we are utilizing a federation service built with NestJS as well. I recently ...

Exploring methods for efficiently handling extensive XLSX files in a Node.js environment

Currently, I am utilizing the ts-xlsx library on the server side to read data. The process involves reading data from the frontend as a byte array using file-reader and then sending this byte array to a library to process the data. However, in cases where ...

Assign the chosen option in the Angular 2 dropdown menu to a specific value

Currently, I am utilizing FormBuilder in order to input values into a database. this.formUser = this._form.group({ "firstName": new FormControl('', [Validators.required]), "lastName": new FormControl('', [Validators.required]), ...

Developed using esbuild, this Angular application outputs to the browser directory

Recently, I updated an application to Angular 17 and the current configuration in angular.json is as follows: "outputPath": "../SFPD.Workflows/wwwroot", It is crucial for the compiled application to be placed in this specific directory ...

Tips for organizing an NPM package containing essential tools

Currently facing the challenge of creating an NPM package to streamline common functionality across multiple frontend projects in our organization. However, I am uncertain about the correct approach. Our projects are built using Typescript, and it seems th ...

What is the best way to retrieve both the checked and unchecked values from a collection of checkboxes?

Check Out This live Example: I am in the process of creating a list of checkboxes with various data objects: data = [ { Key: "class_id", displayName: "Section ID", enabled: true }, { Key: "room_l4", displayName: "Location", enabled: false }, { Key: "se ...

What methods does Angular use to display custom HTML tags in IE9/10 without causing any issues for the browser?

Exploring web components and utilizing customElements.define tends to cause issues in IE9/10. I've noticed that Angular is compatible with IE9/10, and upon inspecting the DOM tree, it seems like Angular successfully displays the custom element tags. ...

Oops! An error occurred: Uncaught promise in TypeError - Unable to map property 'map' as it is undefined

Encountering an error specifically when attempting to return a value from the catch block. Wondering if there is a mistake in the approach. Why is it not possible to return an observable from catch? .ts getMyTopic() { return this.topicSer.getMyTopi ...

Error message stating 'Module not found' is displaying in the browser console

As a beginner with Angular CLI, I recently executed the following commands at the root of my Angular project. issue-management\src\webui>ng generate module pages\dashboard issue-management\src\webui>ng generate component pag ...

Can SystemJS, JetBrains IntelliJ, and modules be combined effectively?

Looking for some clarification on the functionality of module includes and systemJS within an Angular2 app structure. I have set up a basic Angular2 app with the following layout: -app |-lib (contains shims and node libraries) |-components |-app |-app. ...