I am new to angularjs. My goal is very simple. I want to make an ajax call to get data and, once complete, I want to make a second call to get another set of data that is dependent on information in the first set.
I'm trying to do this utilizing promise mechanisms so that I can utilize chaining instead of nested ajax calls and to better retain the ability to have independent functions that I can tie together as needed.
My code resembles the following:
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);
},
// data contains the response
// status is the HTTP status
// headers is the header getter function
// config is the object that was used to create the HTTP request
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, when I look at my debug console, I see that the call to "promiseGetRecentActivities" is beginning before the call the Ajax handling has occurred for "promiseGetWorkTypes".
What am I missing or doing wrong here?
When you write
promiseGetWorkTypes($q, $http, $scope).then(promiseGetRecentActivities($q, $http, $scope));
the promiseGetActivites
is called at the time this line is evaluated. You should be able to wrap the call to promiseGetActivities
in another function to delay the call until the first promise has resolved to get the calls to run in sequence:
promiseGetWorkTypes($q, $http, $scope).then(function() {
promiseGetRecentActivities($q, $http, $scope);
});
The reason isn't anything to do with what happens inside then
, but due to Javascript syntax. The following:
myFunc1(myFunc2());
passes to myFunc1 the result of calling myFunc2()
, and not a reference to the myFunc2
function. So logically, myFunc2
would have to run before myFunc1
. If you wrote
myFunc1(myFunc2);
then myFunc1
will receive a reference to myFunc2
, and so myFunc1
would run before myFunc2
(and in fact, myFunc2
will only run if somewhere inside myFunc1
there is code that calls it).
Defining a function inline/anonymously doesn't change this behaviour. To pass a result of an anonymous function to another function you can do the following
myFunc1((function() {
return 'something';
})());
which will evaluate the anonymous function first, as its return value, 'something'
will be passed to myFunc1
. To pass a reference to an anonymous function you can do the following:
myFunc1(function() {
return 'something';
});
and then it will be up to myFunc1
whether it will ever call the function passed to it.
Bringing it back to your question, your code:
promiseGetWorkTypes($q, $http, $scope).then(promiseGetRecentActivities($q, $http, $scope));
is passing the result of promiseGetRecentActivities($q, $http, $scope)
to then
, so it must run before then
is run, and so certainly doesn't wait for the promise from promiseGetWorkTypes
to be resolved. What you seem to want is to pass it a function that, when called, runs promiseGetRecentActivities($q, $http, $scope)
, which is what
promiseGetWorkTypes($q, $http, $scope).then(function() {
promiseGetRecentActivities($q, $http, $scope);
});
does.
As a side-note, it seems a bit unusual/overcomplicated to be passing $q
, $http
etc around to various functions, but I think probably beyond the scope of this question to go through alternatives.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With