Successively linking promises together within a for-each iteration

How can I ensure that a foreach loop is synchronous in AngularJS

var articles = arg;

articles.forEach(function(data){
      var promises = [fetchImg(data), fetchUser(data)];

      $q.all(promises).then(function (res) {
           finalData.push(res[1]);
      });
});

return finalData;

I am looking for a solution where the finalData array is returned only after the forEach loop has completed. Is there a way to use promises to chain the execution so that the loop is fully executed before returning the array?

Answer №1

Combining Promises in a foreach Loop

In order to consolidate and chain promises, values or promises are returned to the handler function within the .then method. To merge multiple promises, $q.all is used which itself creates a promise that can be chained.

function retrieveData(argument) {
    var items = argument;

    var assurances = items.map(function(item){
        var subAssurances = [fetchImage(item), fetchUserData(item)];        
        return $q.all(subAssurances).then(function (result) {
             //return for chaining
             return {image: result[0], user: result[1]};
        });
    });

    //consolidate promises    
    var finalAssurance = $q.all(assurances); 
    return finalAssurance;
};

By utilizing the .then method of a promise, new derived promises can be created to form a chain of promises. These chains of promises can vary in length and resolve with another promise, allowing for the postponement of resolution at any point within the sequence.1

The resulting promise will either be fulfilled with an array of users or rejected with the first encountered error. The final resolution can be accessed using the promise's .then and .catch methods.

 retrieveData(arguments)
     .then ( function onFulfilled(objectArray) {
          $scope.users = objectArray.map(x => x.user);
          return objectArray;
     }).catch ( function onRejected(response) {
          console.log("ERROR: ", response);
          throw response
     })
 ;

The Pitfalls of $q.defer

Using $q.defer() can introduce issues such as breaking the promise chain, losing error details, and potentially causing memory leaks if errors are not properly handled. For more insights on this, refer to AngularJS Is this a “Deferred Antipattern”?.

Answer №2

If you want to make changes to your code, try implementing the following:

function fetchCustom(arg) {
    var customData = arg;
    var promises = [], finalResult = [];
    var deferred = $q.defer();

    customData.forEach(function(item) {
          var userPromise = retrieveUser(item);
          userPromise.then(function (response) {
               finalResult.push(response[1]);
          });

          promises.push(fetchImage(item));
          promises.push(userPromise);
    });

    $q.all(promises).then(function() {
         deferred.resolve({finalResult: finalResult, foo: "bar"});
    });

    return deferred.promise;
}

After making these modifications, proceed to call this function and add a final callback:

fetchCustom(arg).then(function(data) {
     console.log("finalResult: ", data.finalResult, data.foo === "bar");
});

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

Angular - Dividing Values within Input Arrays

In the input field available to users, they can enter multiple inputs separated by commas. <div class="container"> Enter your values:<input type="text" multiple #inputCheck> <input type="submit"(cli ...

Access a webpage in an html document using URL variables

In the process of developing an MVC web app without utilizing any MVC framework, I have created an index.html file with a section that dynamically loads all the views as needed by the user. However, I encountered an issue where direct URLs such as www.foo. ...

What is the best way to transfer the array from my function and have it returned?

I've been struggling to successfully pass my array to an external function. Can anyone help me with this? You can find the code that I'm working on in jsbin: https://jsbin.com/kugesozawi/edit?js,console,output. The expected result should be passe ...

Employing ajax.actionlink in mvc4 results in a page refresh

I am working on a view that looks like this: @model IEnumerable<DomainClasses.Class> @{ ViewBag.Title = "لیست "; } <div id="test"> <h2>لیست کلاس ها</h2> <p> @Html.ActionLink("ایجاد کلاس جدی ...

Is the PHP Ajax parameter missing during the upload process?

I'm attempting to do a simple upload, but I seem to be struggling. It could be that I'm not understanding it properly, or perhaps it's just too late at night for me to figure it out. After doing some research, I came across this example on ...

What is the significance of the -infinity value in the JavaScript console?

Recently, while learning JavaScript ES6, I came across a strange result of -infinity on my console when running the following code: let numeros = [1, 5, 10, 20, 100, 234]; let max = Math.max.apply(numeros); console.log(max); What does this ...

How to drop several pins on Google Maps with JavaScript

I am working on incorporating multiple markers into a Google map using ajax, javascript, and php. Although there are no errors in my code, the markers are not appearing as expected. I would greatly appreciate any assistance with this issue. Please refer to ...

Tips for waiting for an event from a specific element in Playwright

Is there a way to await an event on a specific element using Playwright? Similar to page.waitForEvent, but focusing only on a particular element rather than the entire page. More information can be found in the documentation. ...

Sort by Date using AngularJS (Ionic framework)

I'm currently working on displaying an accordion list that is ordered by date. The date information is in JSON format, which can be difficult for users to read. However, if I change the format of the date to make it more user-friendly, I run into issu ...

Matching ranges of values (NSRange) in an array with an array of full names strings using Swift

Issue: I am facing a challenge with a comment string that looks like = "@Scott Winburn and @Ben Bloodworth and @Alex Gonzalez and @Jerry Anderson" I have two arrays: Array 1: Retrieves full names = ["@Scott Winburn", "@Ben Bloodworth", "@Alex Gonzalez ...

How can I parse URL paths in jQuery for ASP.NET?

I want to incorporate "~/" and have it resolved on the client side. Here is an example of what I am trying to do: <a href="~/page.aspx">website link</a> <img src="~/page.aspx" /> In my ASP.NET code, I have my base URLs set up like this ...

Is it possible to define an array within the fixtures and then use it in the main test case in Cypress? What happens if Cypress Fixture throws a Type

Currently, I am conducting a test case utilizing Cypress fixtures. Within the ../cypress/fixtures folder, I have a userdata.json file. However, every time I attempt to run the test, I consistently encounter this error: TypeError - Cannot read properties of ...

Cannot get the before-leave transition JavaScript hook to function properly in Vue.js

I am facing an issue with my variable, transitionName, in the beforeLeaveHook function. Despite attempting to change it to 'left', the value remains stuck at 'right'. Any assistance on resolving this matter would be greatly appreciated. ...

Unable to retrieve button value with material-ui package

My task requires me to retrieve the value of a button, as it contains an ID essential for further steps. Initially, I used a standard button with Bootstrap styling and everything functioned correctly. <button value={row.vacationRequestID} c ...

What is the technique used to initialize the $route object?

Upon attempting to access this.$route in the created() hook, I noticed that it consistently returns an empty object when logged to the console. {path: '/', name: undefined, params: {…}, query: {…}, hash: '', …} fullPath: "/&q ...

Ways to include x-api-key in Angular API request headers

I am attempting to include the x-api-key header in the headers, as shown below: service.ts import { Injectable } from '@angular/core'; import { Http, Headers, RequestOptions, Response } from '@angular/http'; import { Observable } from ...

Learn how to retrieve the accurate file name and file type using CordovaFile and CordovaFileTransfer

I have a project where I need to dynamically load files from a website. When you click on a link in the browser, it loads the files with the correct names and extensions. How can I implement this functionality in an Ionic app? I am unsure of how to go ab ...

Obtaining a phone number from a contact in Nativescript Angular: A step-by-step guide

Upon executing the following code: let desiredFields = ['display_name','phone','thumbnail','email','organization']; console.log('Loading contacts...'); let timer = new Date().getTime(); Contact ...

Create beautiful PDF documents using the KNP Snappy Bundle, seamlessly converting dynamically modified Twig templates

Currently, I am attempting to create a PDF from a tweaked Twig on the client side. My approach involves sending the modified HTML document to the server via AJAX. However, this method is proving ineffective as the server is returning a binary document that ...

What causes adjacent elements in an int array to change when a number is appended in Golang?

I've been working on solving dynamic programming problems using Golang. One of the functions I wrote looks like this: func main() { fmt.Println(HowSum(5, []int{1, 2, 5})) } func HowSum(targetNum int, numbers []int) []int { retAry := make([][]in ...