Fulfill a commitment once all conditional inner promises have been successfully completed following a forEach operation

In my current project, I have a promise that interacts with an array of objects. Depending on the value of each item in the array, another function might be called. If not needed, nothing happens and eventually, it resolves to an object. However, there is an issue where it resolves too early. When the state of a car is already known, everything works fine. But if we need to determine the state dynamically, the promise does not wait for the state to be resolved:

getAggregatedData(obj: StorageUnit): Promise<any> {
    let stat = {
      inStoreCars: 0,
      atWorkCars: 0
    };

    const vm: any = this;

    return new Promise((resolve, reject) => {
      obj.carsList.forEach(car => {

          if (car.inStore) {
            stat.inStoreCars++;
          } else if (car.atWork) {
            stat.atWorkCars++;
          }
          // unknown state. so check its state
          else {


                vm.carStateService
                  .getState(car)
                  .then(value => {
                   if (value == 1){
                       stat.inStoreCars++;
                   }else{
                       stat.atWorkCars++;
                   }
                  });


          }

      });
      resolve(stat) // returning too early before getState() resolves
    });
  }

To use this function, I simply call it like this:

    getAggregatedData(car).then(stat=>{
       console.log(stat)
     });

Answer №1

It would be helpful to have additional information upfront. Creating a function that synchronizes asynchronous operations goes against the natural flow of the event loop, making it an anti-pattern. Instead of using promises, consider utilizing async/await if you are working with TypeScript. Another thing to avoid is generating and running a promise in the same location.

Answer №2

To achieve this task, you won't be able to utilize .forEach(). Instead, you will need to employ the traditional for loop method. Refer to the provided example below (which was adapted from your initial code).

function test() {
        let stats = {
            inStoreCars: 0,
            atWorkCars: 0,
        }
        const carsList = [1, 0, 1, 0];
        return new Promise<any>(async (resolve) => {
            for (let i in carsList) {
                const car = carsList[i];
                stats = await new Promise<any>((res) => {
                    setTimeout(() => res(car), 5000);
                })
                    .then(value => {
                        console.log("then");
                        if (value == 1) {
                            stats.inStoreCars++;
                            return stats;
                        } else {
                            stats.atWorkCars++;
                            return stats;
                        }
                    });
            }
            resolve(stats);
        });
    }
    test().then((val) => alert(JSON.stringify(val)));

I have updated the promise returned by using an async function and incorporated a return statement within the getState().then(), allowing me to await the required changes. You can implement a similar approach by executing

state = await vm.carStateService.getState(...)

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

Displaying svg files conditionally in a react native application

I have developed an app specifically for trading dogs. Each dog breed in my app is associated with its own unique svg file, which are all stored in the assets folder (approximately 150 svg files in total). When retrieving post data from the backend, I re ...

Is there a way for me to set a variable in my component with a value from the Angular Material autocomplete feature?

I am currently in the process of constructing a form to generate a POST request to the API. I have opted to utilize Angular Material 4 and incorporate the Autocomplete component provided by Material Design. Below is the code snippet displaying my HTML Com ...

The Angular CLI seems to be having trouble locating modules that are clearly present within the workspace

After deleting a component and recreating it with the same name and folder structure using the CLI, I encountered an error. The CLI began throwing errors stating it couldn't find modules that were clearly present and untouched. These modules are simpl ...

Angular 4 animation issue: duration of transitions not being properly implemented

Why isn't the transition working as expected? Even though the animate function is set with a time of 2 seconds, the transition happens instantly. trigger('showMenu', [ state('active', style({ marginLeft: '0px' }) ...

Storing multiple fields using LocalStorage in Angular2

After finding inspiration from the example at https://github.com/PillowPillow/ng2-webstorage, I successfully managed to store and retrieve the boundValue. Now, I encounter a new challenge with a list of bots: bot.component.html <tr *ngFor="let bot of ...

Template literals in Typescript provide a powerful way to define string templates with

Here is the code I am working with: type CustomType<T extends string = string> = `custom-${T}-type`; const value: CustomType = 'custom-example-type'; The code above functions as expected, but it does not enforce the expected structure. Th ...

Which is better for storing a collection of Components in a Service: Array or QueryList?

I have developed a PopupService with the following structure: export class PopupService { popups: PopupComponent[] = []; open(popup: PopupComponent) { this.popups.forEach(popup => popup.active = false); popup.active = true; } close(p ...

Can we verify if this API response is accurate?

I am currently delving into the world of API's and developing a basic response for users when they hit an endpoint on my express app. One question that has been lingering in my mind is what constitutes a proper API response – must it always be an o ...

I'm curious if it's possible to set up both Tailwind CSS and TypeScript in Next.js during the initialization process

When using the command npx create-next-app -e with-tailwindcss my-project, it appears that only Tailwind is configured. npx create-next-app -ts If you use the above command, only TypeScript will be configured. However, running npx create-next-app -e with ...

The function service.foo is not recognized in Angular

My service function is not being recognized by my component import { Injectable } from '@angular/core'; import { ToastController } from '@ionic/angular'; @Injectable({ providedIn: 'root' }) export class LocationService { ...

Angular Universal - Transfer state does not populate correctly when the URL contains unsafe characters, leading to duplicate XHR calls

Working with Angular(12) and Angular Universal has presented me with a challenge regarding the transfer state between the server and client side. On the client side, I am using the TransferHttpCacheModule, while on the server side module, I have implemente ...

Monitor changes in a dynamic child component using Angular fire and TypeScript only (no HTML)

Currently, I am developing a component using TypeScript and passing inputs to my child component from there. In the parent TypeScript file: this.childComponent = this.viewContainerRef.createComponent(this.data.body).instance; this.childComponent['chi ...

An issue arises when trying to update state using useState in TypeScript

In our system, we have a state that contains an array of objects: interface Product { id: number; status: boolean; color: string; price: number; } const productList: Product[] = [ { id: 1, status: true, color: 'yellow', ...

Navigating using ViewChild in Ionic 2 Beta

I recently updated my Ionic 2 app to use Angular 2 RC1, which has been a great improvement. However, I am facing some challenges with the routing implementation. Despite following the update guide, I still encounter issues with my navigation component bein ...

After importing the shared module in a feature module, Angular components declared in the shared module are not being recognized in the feature modules

I have successfully imported the shared module into my appModule and utilized one of its components without any issues. However, I encountered a problem when I tried to import the shared module into my feature module. Shared Module: @NgModule({ imports ...

The TypeScript function was anticipating one argument, however it received two instead

Can you help me fix the issue with my createUser() function? Why am I unable to pass parameters in Smoke.ts? Login.ts : interface User { url: string, email: string, } class Test{ async createUser(user: User) { await Page.setUrl(user.url); aw ...

Utilize rxjs to effectively handle API data responses and efficiently manage the state of your application within Angular 10

I'm currently exploring the most efficient method for storing and updating data from an API, as well as sharing that data among sibling components. Here's my initial attempt: Storing the Observable export class MyExampleService { private data ...

After changing routes in Angular 4, the application experiences decreased speed and a continual increase in the number of nodes, particularly noticeable in Chrome but not in Firefox

After switching routes multiple times, I noticed a decrease in the app's speed. Upon inspecting the 'performance + memory' section using Chrome debugger, I observed an increasing number of DOM nodes. It seems that the DOM nodes are not prop ...

I'm struggling to include a link in my project card component - I've tried using both the Link tag and anchor tag, but so far, I haven't been successful in

I am having trouble getting the link tag to work properly in my UI. I have tried using both the link and anchor tags, but neither seems to be functioning as expected. Can someone please advise on how to fix this issue? https://i.sstatic.net/tAD7C.png I w ...

Enable automatic conversion of interfaces to JsonData

Is it possible to tweak this Json data type definition to allow json-compatible types to automatically convert to it? type JsonValue = | string | number | boolean | null | { [property: string]: JsonValue } | JsonValue[]; Consider t ...