I created following controller with 2 service calling with services. Second response comes before then first. i want to do like i need first response first and second response second. but i just stuck with async and sync please help me for solving.
Second call is depends on first call. For example if first call returns 10 record then i have to call second web service 10 time taking id from first response. so i use for loop but it is not proper.
var mycompaigndata = [];
asyncService.loadDataFromUrls($http.get(WSURL + 'api/first/',
{
headers:
{
"Authorization":'Bearer <my-token>'
}
}))
.then(function(data)
{
console.log(data);
});
asyncService.loadDataFromUrls($http.get(WSURL + 'api/second',
{
headers:
{
"Authorization":'Bearer <my-token>'
}
}))
.then(function(data)
{
console.log(data);
});
app.service('asyncService', function($http, $q)
{
return {
loadDataFromUrls: function(url)
{
var deferred = $q.defer();
var urlCalls = [];
urlCalls.push(url);
$q.all(urlCalls)
.then(
function(results)
{
deferred.resolve(results)
},
function(errors)
{
deferred.reject(errors);
},
function(updates)
{
deferred.update(updates);
});
return deferred.promise;
}
};
});
To make sure the second calls are executed after the first one is finished, put the second call within then
of the first call. To make multiple 'second' calls depending on the number of results of the first call, use $q.all
.
asyncService.loadDataFromUrls('api/first/')
.then(function(firstData) {
//assuming firstData is an array of 'x' items, do a call for each of these items:
console.log('results of first call holds ' + firstData.length + ' items');
var promises = [];
for(var i = 0; i<firstData.length; i++){
var id = firstData[i].id;//you can use this to pass to the second call
promises.push(asyncService.loadDataFromUrls('api/second'));
}
return $q.all(promises);
})
.then(function(results) {
//'results' is an array of results, the nth item holds the result of the 'nth' call to loadDataFromUrls
for(var i = 0; i<results.length; i++){
console.log('result nr. ' + i + ' :' + results[i])
}
});
By using return $q.all(promises)
, you're avoiding the promise pyramid of doom, and keep a flat structure.
Your service code doesn't need to loop anymore. As a sidenote, you can shorten the code of the service and avoid using the 'explicit promise construction antipattern' (see here) like this:
app.service('asyncService', function($http, $q)
{
return {
loadDataFromUrls: function(url)
{
return $http.get(WSURL + url, {
headers: {
"Authorization": 'Bearer <my-token>'
}
}).then(function(response){ return response.data; });
}
};
});
Your asyncService
seems completely unnecessary and unuseful.
It sounds like you just need to learn how to chain promises and use $q.all
correctly:
function queryApi(subUrl) {
return $http.get(WSURL + subUrl, {
headers: {
"Authorization":'Bearer <my-token>'
}
}).then(function (result) { return result.data; });
}
queryApi('api/first/')
.then(function (data) {
return $q.all(data.map(function (entry) {
return queryApi('api/second/' + entry.id);
}));
})
.then(function (results) {
console.log(results);
});
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