$http promise chain executing in an incorrect sequence

As a beginner in angularjs, my objective is straightforward. I aim to execute an ajax request to fetch data and, upon completion, I want to initiate a second call to retrieve another set of data based on the information from the initial set.

To achieve this, I am utilizing promise mechanisms to enable chaining instead of nesting ajax calls. This helps in maintaining independent functions that can be linked together as needed.

Here is a snippet of my code:

var promiseGetWorkTypes = function ($q, $scope, $http) {
console.log("promiseGetWorkTypes");

return $q(function (resolve, reject) {
$http({
method: 'GET',
url: '/WorkTypes'
}).then(
function (payload) {
console.log("Got workttypegroups")
console.log(payload);

$scope.WorkTypeGroups = payload.data;

console.log("End of worktypegroups");
resolve(payload);
},
function (payload) {
reject(payload);
});
});
};

var promiseGetRecentActivities = function ($q, $scope, $http) {
console.log("promiseGetRecentActivities");

return $q(function (resolve, reject) {
$http({
method: 'GET',
url: '/RecentHistory'
}).then(
function (payload) {
$scope.RecentActivities = payload.data;

resolve(payload);
},
function (payload) {
reject(payload);
});
});
};

var index = angular.module("index", []);

index
.controller('EntitiesController', function ($scope, $http, $timeout, $q) {
promiseGetWorkTypes($q, $http, $scope)
.then(promiseGetRecentActivities($q, $http, $scope));
}

However, upon checking my debug console, I noticed that the call to "promiseGetRecentActivities" is starting before the completion of the Ajax handling for "promiseGetWorkTypes".

What could be the issue or mistake in my approach here?

Answer №1

When you type out

promiseGetWorkTypes($q, $http, $scope).then(promiseGetRecentActivities($q, $http, $scope));

the promiseGetActivities function is executed when this line is processed. To ensure that the calls happen in sequence, you can enclose the call to promiseGetActivities in another function so that it executes only after the first promise has been resolved:

promiseGetWorkTypes($q, $http, $scope).then(function() {
  promiseGetRecentActivities($q, $http, $scope);
});

The reason for this behavior is not related to the operations within the then method, but rather due to the syntax of Javascript. In the following example:

myFunc1(myFunc2());

the result of calling myFunc2() is passed to myFunc1, not a reference to the myFunc2 function. Consequently, myFunc2 will run before myFunc1. If you had written

myFunc1(myFunc2);

then myFunc1 would receive a reference to myFunc2, and would run before myFunc2. Defining a function inline does not change this behavior. To pass the result of an anonymous function to another function, you can do the following:

myFunc1((function() {
  return 'something';
})());

which evaluates the anonymous function first and passes its return value to myFunc1. To pass a reference to an anonymous function, you can do the following:

myFunc1(function() {
  return 'something';
});

Regarding your code, the line:

promiseGetWorkTypes($q, $http, $scope).then(promiseGetRecentActivities($q, $http, $scope));

is passing the result of

promiseGetRecentActivities($q, $http, $scope)
to then, which means it has to run before then, without waiting for the promise from promiseGetWorkTypes to be resolved. To achieve the desired outcome, you should pass a function that executes
promiseGetRecentActivities($q, $http, $scope)
when called, like so:

promiseGetWorkTypes($q, $http, $scope).then(function() {
  promiseGetRecentActivities($q, $http, $scope);
});

It may seem a bit complex to be passing $q, $http, etc. to multiple functions, but discussing alternatives is beyond the scope of this question.

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

The failure of a unit test involving Jest and try-catch

I am facing an issue with creating unit tests using jest. exportMyData.js const createJobTrasferSetArray = async () => { const data = exportData(); const jobTransferSet = []; try { data.forEach((element) => { const JobPathArray = el ...

Efficiently configuring an Array with Wordpress REST API in JavaScript

Here's a two-part question: 1) My goal is to fetch elements from WordPress' REST API and store them in an array called map_locations. The first part of the function involving $.ajax works as intended, showing data when I log it. However, the lat ...

Tips for choosing a visible element in Protractor while using AngularJS

I am working on a Single Page Application that contains multiple divs with the same class. My goal is to have protractor identify the visible div and then click on it. However, I keep encountering the error Failed: element not visible, which leads me to be ...

I am facing an issue where reducing the size of the renderer is causing my click events to be offset. What steps can I

At the moment, my rendered model (which is grey in color) stretches across the entire width of the html page with the mesh centered within that width. I want to reduce this width but when I do so, the click event on the model seems to be misaligned. Three. ...

Unlock the Power of Vue Draggable in Vue.js 3 with These Simple Steps

When attempting to implement Draggable in Vue.js 3, I encountered an error message: VueCompilerError: v-slot can only be used on components or <template> tags. Below is a snippet of my code: <draggable tag="transiton-group" name="s ...

managing multiple web browsers simultaneously during protractor end-to-end testing tasks

While conducting E2E testing for an angular web chat application with protractor as the chosen E2E framework, I am interested in opening and controlling two browsers simultaneously to simulate a real chat environment and validate all expected outcomes. Is ...

Why is this specific element showing as undefined in the form during editing, but appearing correctly in both the debugger and console.log?

I've encountered an error that keeps popping up: "Cannot read property 'textContent' of undefined at HTMLDocument". This error specifically occurs when dogName, dogBreed, and dogSex are set within the 'click' listener. It's st ...

Choose an option removed upon clicking

I need to remove the option with a value of 0 when the user selects from the dropdown list. Choose: <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <form:select id="CONTEXTE" path="CONTEXTE" onclick="go()" class="s ...

implementing django-recaptcha validation in django using ajax form

I recently implemented a small contact form that utilizes ajax for submission. To enhance security, I integrated a recaptcha feature using the django-recaptcha module. After validation of the form, there seems to be an issue with the captcha field as it a ...

JavaScript's connection to the CSS property visibility seems to be causing some issues

The Javascript code seems to be ignoring the CSS display property, even though it's set in the style sheet. I added a debugger statement and noticed that the display value was empty. I've been staring at this for some time now, so I must be overl ...

Using Conditions in a Javascript For Loop

I would like to utilize a for loop to achieve the following task. Within an array, I have a predefined set of values representing hex colors for a chart. My goal is to extract a specified number of those values using the loop with two options. If the ...

Triggering a function without the presence of an actual event

I need to come up with a solution for reusing a function triggered by an event binding. This problem stems from browsers remembering checkbox states, which is why I have to call the function on document load. One approach could involve wrapping setGrid() ...

Guide on how to refresh the background image using the identical URL within a directive

I am looking to refresh the background image of a div using the same URL within a directive. Upon loading my view, I utilized this directive to display the image as a background for the div. app.directive('backImg', function () { var dir ...

Dynamically select checkbox groups based on items already listed in a textarea

Hello! Would you be able to review this example and provide guidance on how I can use jQuery to dynamically select the checkboxes that have the same text as in the textarea below? <br /> <br /> Default Items From Database <br /> < ...

Tips for extracting Stripe response post payment using a client-side-only integration

My current component handles sending a payment order to my stripe account on the client-side. Everything seems to be working fine, but I'm struggling to find a way to retrieve the response or token from stripe containing the order details, which I nee ...

Extract information from a webpage using Selenium WebDriver

Currently, I am working on mastering Selenium, but I have hit a roadblock that I need assistance with. My task is to gather all the betting information for games from the following link and store it into an array. Given my limited experience with HTML an ...

Content submission and updates, modeled after the Twitter platform

Hello there. I am currently working on a quotation service and ran into an issue while attempting to implement twitter-like data submission and display: all of my ajax requests seem to be executed twice. I am using jQuery in the following manner: I hav ...

Unable to upload file on ReactJS platform

I'm facing an issue while trying to upload a file and text using a form. The file doesn't get uploaded, although it works fine with Postman. Can anyone identify the problem? Thank you Axios function : postArticles : (content, attachment, header ...

What is the best way to pass and save information across different routes in Express using Node.js?

Let's delve into the specific functionalities I envision for my server. Essentially, my project involves user registration and login processes. The URLs for these routes are as follows - localhost:3000/login and localhost:3000/register Upon successf ...

The blur() function in -webkit-filter does not seem to function properly in Vue.js

I'm having trouble implementing the -webkit-filter: blur() property. I tried using "filter" instead, but it still isn't working. Could this be a limitation of Vue.js or are there any other solutions available? <template> <div class=&qu ...