Continue iterating only when all promises have been resolved

My AngularJS requirement involves the following:

 for (var i = 0, len = self.Scope.data.length; i < len; i++) 
{

         var data = self.Scope.data[i];
         var self = this;
//Executing First asynchronous function
self.EcritureService.createNewData(data).then(() => {
         })                                                     
//Executing Second asynchronous function
self.OperationService.getOperation(data.idOperation).then((operation) => {

         })   
//Executing Third asynchronous function
self.AccountService.getAccount(data.codeCompte).then((compte) => {
               currentAccount = compte;
               currentAccount.montant = currentAccount.montant+data.montant;
         })   
//Executing Fourth function depending on the third result to execute sequentially
self.AccountService.updateAccount(currentAccount).then(() => {
         })                    
}
// Once all promises from the fetch loop are resolved, I need to proceed with additional steps to update the operation fetched in the second function

I require the loop iterator to wait until all promises are resolved before proceeding to the next step and ensuring that all tasks are completed before moving to the final functionality outside the loop block.

Answer №1

Generate arrays containing promises and utilize $q.all(promise_array) to execute when all promises are successfully resolved

// create an array of `$q.all()` promises
let promises = self.Scope.data.map((data) => {
  //First asynchronous function
  let promise_1 = self.EcritureService.createNewData(data).then(() => {})
  //Second asynchronous function
  let promise_2 = self.OperationService.getOperation(data.idOperation).then((operation) => {

  })
  //Third asynchronous function
  let promise_3 = self.AccountService.getAccount(data.codeCompte).then((compte) => {
    currentAccount = compte;
    currentAccount.montant = currentAccount.montant + data.montant;
    return currentAccount;
  }).then((currentAccount) => {
    //return promise of 4th inside `then()` of third
    return self.AccountService.updateAccount(currentAccount).then(() => {});
  });

  // this `$q.all()` resolves when this mapped instance of above all resolve
  return $q.all([promise_1, promise_2, promise_3]);

});

// resolves when all the loop instances of `$q.all()` resolve
$q.all(promises).then(()=>{
  // run completion code here
}).catch(err=>{
  console.log('Something failed in promise chain')
})

Answer №2

Initially, it's worth noting that transforming those services into promises may not be the ideal approach since you aim to avoid their inherent "promiseness." The most straightforward fix would involve revising the services to return values conventionally instead of via promises.

To address your inquiries, let's start with the latter part first. The simplest way to link the fourth promise to the third is by nesting it within the third .then block, as depicted below:

//Code for the third asynchronous function 
self.AccountService.getAccount(data.codeCompte).then((compte) => {
           currentAccount = compte;
           currentAccount.montant = currentAccount.montant+data.montant; 
           //The fourth function relies on the outcome of the third, so it should run sequentially
           self.AccountService.updateAccount(currentAccount).then(() => {
     })  
 })

If error handling is in place, you might consider placing the nested promise inside a .finally clause instead.

Regarding making the loop wait, standard for loops are not built for that purpose. To achieve this, you could create a custom loop and utilize $q.all to combine the promises. It would involve keeping track of a loop counter, incrementing it in the .then block of $q.all, and employing a recursive function that terminates once the necessary number of loops is completed.

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

no such file exists in the directory

My current project involves connecting a javascript file to an html file using the <script> tag. However, upon rendering the html page, I encountered an error in the console indicating that the javascript file could not be located. Here is the struc ...

The formValidation, previously known as BootstrapValidator, is causing issues with my form submission via Ajax, despite my efforts to update the code to work with

I recently upgraded the old BootstrapValidator to the new 0.6.0 release known as formValidation. Despite reading the documentation multiple times, I have been unsuccessful in finding the issue and need some assistance. Below are the CSS styles and scripts ...

Is JSON.stringify failing to function correctly in Mozilla Firefox?

Currently, I am attempting to convert an object into a string in javascript. After stringifying the object, I have noticed some discrepancies between different browsers. {"jobTypeArray":"[CONTRACT -W2]"} In Firefox and Chrome, the values appear as follow ...

AngularJS: incorporating various functionalities within a single controller

I have a basic AngularJS controller that I am working on, and I would like it to include two separate functions: var app = angular.module('searchApp', []); app.controller('searchCtrl', function($scope, $http, $log) { //Function 1 ...

Is it necessary for React components to be organized in a hierarchy?

In all my years, I've been told that React components should follow a tree hierarchy so that parent components can manage state and pass it down to their children. But is this truly necessary? The guiding principle of React states that "React has bee ...

Leverage Express JS to prevent unauthorized requests from the Client Side

Exploring the functionalities of the Express router: const express = require("express"); const router = express.Router(); const DUMMY_PLACES = [ { id: "p1", title: "Empire State Building", description: "One of the most famous sky scrapers i ...

Triggering the onClick event in React to invoke another class components

I'm currently working on implementing a modal popup (stored in the PostView class) so that it appears when any post in the postcontainer class is clicked. As I am new to React, I would greatly appreciate any suggestions for enhancing the code. Post C ...

Tips for enhancing the fluidity of animations after removing an item from a list

I'm working on a project where I have a list of elements that are removed with an animation when clicked. However, I noticed that when one element is removed, the rest of the elements just jump up instead of smoothly transitioning. Is there a way to m ...

Tips for retrieving a flag when there is a preexisting record within an association in Sequelize

I am working with a model A that has a 1:N association with a model B. My objective is to retrieve all records from A and determine whether there is at least one associated record from B (true) or not (false). The relationship setup: ModelA.hasMany(ModelB ...

Error thrown when attempting to access properties of null values (Uncaught TypeError: Cannot read properties of undefined (reading 'map'))

import React, { useState, useEffect } from "react"; import { TaskLists } from "./TaskLists"; import { Daycard } from "./daycard"; import { getTasks, deleteTask } from "../api/task.api"; export function TaskManager() { const [tasks, setTasks] = useState( ...

Trigger .gif on hover using ng-repeat in AngularJS

Many solutions to this problem involve using jQuery, such as the following examples: Stop a gif animation onload, on mouseover start the activation and Animating a gif on hover. However, I'm interested in achieving the same functionality using Angular ...

Signaling an Event from a module in the node_modules directory to the Vue application

Is there a way to capture an event emitted by a node module and receive it in a Vue file? Sample code from the JavaScript node module: const EventEmitter = require('events') class Find extends EventEmitter { // code snippets here } class Fin ...

What is the best way to keep the heights of two divs in sync?

Is there a way to make two divs have the same height, even though their content determines their individual heights? I am looking for a solution that doesn't involve using a table or a parent div. I'm new to JavaScript, so I'm hoping there i ...

Is it possible to append an "index" to a database field using Express, Loopback, or NodeJS?

Currently, we are utilizing the Express/Loopback Framework for our backend. I am currently working on ensuring that indexes on certain fields in models are properly created in MongoDB. Is there a way to utilize meta-tags within the models so that DataJuggl ...

Tips for enhancing undo/redo functionality when working with canvas drawings in React

Currently, I am working on implementing undo/redo functionality for html-canvas drawing on medical (.nii) images in a React application. The images consist of slices stored in a Uint8ClampedArray and usually have dimensions around 500 (cols) x 500 (rows) x ...

The arrangement of a table, an iframe, and another table being showcased in close proximity

I need assistance in aligning a table, an iframe, and another table side by side without any breaks. Ideally, I would like all three elements to be centered on the page. It seems odd that they're not displaying next to each other as my screen is larg ...

Engage in a Play app featuring AngularJS frontend navigation

Currently, I am using the Play Framework to develop a REST service and I would like the front end to be built with Angularjs in order to make rest calls. I have configured a route provider as follows: angular.module("getAbscencePlans", ["getAbscencePlans. ...

Creating a test suite with Jasmine for an Angular ui-grid component compiled without using $scope

I have encountered an issue while using $compile to compile a ui-grid for Jasmine testing. Initially, everything worked smoothly when I passed $scope as a parameter to the controller. However, I am now transitioning to using vm, which has resulted in $comp ...

Enhancing Angular's templates and handling cache invalidation

I have encountered a dilemma in my Angular1 project where changes made to an html template are not immediately visible to users without performing a hard refresh. Ideally, I would like to implement a cache service that checks for a timestamp and invalidate ...

What is the best way to save high-resolution images created with HTML5 canvas?

Currently, there is a JavaScript script being used to load and manipulate images using the fabricjs library. The canvas dimensions are set to 600x350 pixels. When smaller images are uploaded onto the canvas and saved as a file on disk, everything works c ...