Using Promise.all in TypeScript does not automatically trigger asynchronous calls

I need to handle multiple async API calls using Promise.all after they have all returned and resolved.

if(this.selectedDomains.length > 0) {
      for(let i=0; i<this.selectedDomains.length; i++){
        promises.push(

          this.policyService.exportPolicies(this.selectedDomains[i].id, this.config['data'].policies)


        );

      }

      //wait for all exportPolicies calls to finish
      Promise.all(promises).then(function () {
        console.log("ALL resolved !!");
          let successMsg = this.translate.instant("policy.resources.export_policy_success",
            [this.config['data'].policies.length, this.selectedDomains.length]);
          this.messageHelperService.showSuccess({hide: true, message: successMsg});
        }
      ).catch(function () {
      });
    }

In the code above, this.policyService.exportPolicies is an async API call that never gets executed, but I still see the console message "ALL resolved !!"

How can we ensure that Promise.all resolves only after all the async API calls in the promises array have been resolved?

Here are the details of the API call:

export class PolicyService {

  constructor ( private baseService : BaseService ) {
  }
  exportPolicies(domainId, policyIds) : Observable<import("@angular/common/http").HttpEvent<any[]>>{
    let url = COMMON.LEGACY_API_PATH + `policy/exportPolicy/${domainId}`;
    return this.baseService.postData(url, policyIds);
  }
export declare class BaseService {
    private http;
    constructor(http: HttpClient);
    handleError<T>(operation?: string, result?: T): (error: any) => Observable<T>;
    log(message: string, response: object): void;
    deleteData(url: string, data?: any): Observable<import("@angular/common/http").HttpEvent<any[]>>;
    getData(url: string): Observable<any[]>;
    postData(url: string, data?: any, params?: any): Observable<import("@angular/common/http").HttpEvent<any[]>>;
    putData(url: string, data?: any, params?: any): Observable<import("@angular/common/http").HttpEvent<any[]>>;
    patchData(url: string, data?: any, params?: any): Observable<import("@angular/common/http").HttpEvent<any[]>>;
    headData(url: string): Observable<any[]>;
    static ɵfac: ɵngcc0.ɵɵFactoryDef<BaseService, never>;
}

Answer №1

From what I can gather, the function exportPolicies is expected to return an Observable. When you use

promises.push(this.policyService.exportPolicies(...))
, you are essentially adding an Observable to an array named promises. The issue arises when you try to use Promise.all on an Observable, which doesn't properly handle it and just returns the original observable.

To address this, you can convert the Observable to a Promise before pushing it into the array:

promises.push(this.policyService.exportPolicies(...)).toPromise();

To prevent such problems in the future, consider defining the type of promises explicitly, for example:

const promises: Promise<MyType>[] = []
. This way, your TypeScript compiler would catch any issues beforehand without having to run the code at all :-).

Answer №2

To tackle this challenge, you have two main options: transform your Observables into Promises and leverage Promise.all, or opt for the Observable alternative to Promise.all known as forkJoin

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

Is it possible to use the same identifier for both the name and id attributes in HTML?

In the world of coding, the "name" attribute is often used in server-side programming to send name/value pairs in requests. On the other hand, the "id" attribute is commonly utilized in client-side programming such as Javascript and CSS. However, both att ...

Leveraging ng-selected in AngularJS to effortlessly select multiple options from a collection

Two arrays of objects are causing me some confusion, with one array being a subset of the other: $scope.taskGroups = [ {id: 1, name: 'group1', description: 'description1'}, {id: 2, name: 'group2', description: 'descr ...

A step-by-step guide on utilizing the getByRole function in react-native-testing-library

Having trouble using the getByRole function in react native testing library and struggling with the syntax. The component I'm working with: <Text accessibilityRole={'button'} accessibilityLabel={'upvote count'} style={[s ...

What was the reason for the failure of the setState function in this particular instance within NextJS?

Greetings everyone! I'm encountering an issue - the setState function is not functioning in my NextJS + TS application. I attempted using state with ReactHooks, switched the component to classes, but to no avail. Interestingly, when I tested ...

Can a form be submitted using ViewChild in Angular5?

Can a form be submitted using ViewChild in Angular5? If so, how can it be achieved? I attempted to do this but was unsuccessful My Attempt: <form #form="ngForm" (submit)="submitForm(form)" novalidate> <input required type="text" #codeReques ...

Using CSS transition on the height property does not produce the desired effect

I'm currently working on a menu interaction that activates on click. Here is the code snippet for reference: let btn = document.querySelector('.trigger'); let icons = document.querySelector('.icons'); let labels = document.query ...

What is the process for converting primitive values in the expressions `1 + {}` and `{} + 1`?

Being a novice developer, I am struggling to comprehend why the following statements result in different outputs. Could someone please explain why JavaScript interprets these two expressions differently and produces distinct outcomes? 1 + {} // => "1[o ...

"Enhance the functionality of material-table by incorporating a multi-select feature

My data management has been made easier with Material-Table, but I have encountered a small issue. The code below shows how I currently get a select menu for my data. However, I am looking to have a multiselect menu instead, allowing me to save more than o ...

Utilizing Algolia backend search capabilities enhanced by the Algolia Search Helper library specifically designed for Angular.js

I'm considering sending the search request to Algolia using the backend for security reasons. I came across information here stating that Instantsearch allows this by specifying a custom customSearchClient and passing it as a parameter. Even though I ...

What is the best way to update all React components with a context without using a provider?

Considering this straightforward custom hook import React, { createContext, useContext } from 'react'; const context = { __prefs: JSON.parse(localStorage.getItem('localPreferences') || null) || {} , get(key, defaultValue = null) ...

Create logic statements based on the information obtained from parsing an XML document

Looking for some assistance with writing this code. Any help is appreciated! Let's say I am extracting data from an XML file like the following: function parseXml(xml) { $(xml).find("ITEM").each(function() { var foo = $("bar", this).text ...

I'm currently working on a React toaster component, but I'm facing an issue where it's not displaying

I have created the Toaster component programmatically and I am passing the message through another component. This is how my Toaster component looks: export default class MyToaster extends React.Component { constructor(props) { super(props); ...

Encountering an error while transmitting variables through ajax

Encountering an issue when attempting to remove a user from the database. Below is the code I have written: On the server side: @RestController public class EmployeeRestController { @DeleteMapping( value = "/delete_user") public List<Em ...

Using a JavaScript file within a webpage that has already been loaded

Seeking assistance as I encounter a dilemma: providing code would be overwhelming, but perhaps someone can assist me in brainstorming a solution. Here's the issue: I have an index.php file with a div that dynamically loads (via jQuery .load()) another ...

When trying to make edits, the cursor automatically jumps to the end of the field

In Safari, there is a strange issue occurring with a text field used for emails. When entering text and trying to edit by moving the cursor, new characters are automatically placed at the end of the text. It seems that the problematic code causing this beh ...

What's the reason for Webstorm's Angular (TSLINT) alert when the attribute "_id" is defined in the model?

Currently I am working on a MEAN app, where I aim to define the user "_id" in my model as per MongoDB/Mongoose standards. I wish for properties like "id" to be as transparent as possible, however there seems to be an issue." According to tslint, variable ...

Error: The term 'function' is not recognized in this Javascript runtime

There seems to be an issue with my function being undefined, even though it is clearly defined below the content of the program. <button type="button" class="btn btn-primary" data-dismiss="modal" id="CmdBranchEditOk" onclick="CmdBranchEditOk_OnCli ...

Dynamically assigning values to class properties in Angular with Typescript is a powerful

I am working on a project where I have a class and a JSON object. My goal is to update the properties in the class based on the values in the JSON object, using Angular 9. This is the class: export class Searchdata{ name:boolean=false; age:boolean=fa ...

The functionality of the photo swipe feature in HTML is currently not functioning as intended

I have been struggling to integrate photoswipe.js for swiping images in my project, but unfortunately the swipe functionality is not working as expected. head <script type="text/javascript" src="js/klass.min.js"></script> <script type="tex ...

What methods are available to modify the colors in an Apex bar chart?

Currently, I am in the process of constructing a bar chart using react, mui, and apex-chart. One specific requirement I have is to modify the colors of the bars displayed on the chart. Despite my efforts in attempting various solutions, I have been unsucce ...