Je suis en train d'essayer de parcourir un tableau que je construis à partir de plusieurs appels http dans un angular.forEach()
la fonction
$scope.ticket_stats = function(){
//cleaning variables
$scope.data_set = [];
$scope.closed_tickets = [];
//fetching time stamps (Epoch)
$scope.time_frame = time_period.days(7);
//calling data using time stamps
angular.forEach($scope.time_frame, function(item) {
//debug
console.log(item);
var promise = tickets.status("closed", item);
promise.success(function(data){
console.log(data);
$scope.closed_tickets.Push(data[0].datapoints[0][0]); // returns a numerical value
});
});
//SEE MESSAGE BELOW
$scope.data_set.Push($scope.closed_tickets);
}
la dernière ligne $scope.data_set.Push()
fonctionne mais s'incrémente dans le temps une fois que les appels renvoient des données. Je voudrais que cette ligne soit exécutée une fois que tout est dans la boucle for Each. J'ai besoin d'itérer sur le tableau $scope.closed_tickets
pour pouvoir lire (additionner) des données qu'il contient et créer un second tableau.
voici les services utilisés dans cette fonction:
// CALL TICKETS STATS
app.service('tickets', function($http){
this.status = function(status, date){
var one_snap = date - 100;
var url = "/url/render?format=json&target=sum(stats.tickets."+status+")&from="+one_snap+"&until="+date+"";
return $http.get(url);
};
});
// TIME STAMPS MATHS
app.service('time_period', function(){
var currentDate = parseInt((new Date).getTime()/1000);
this.days = function(number){
var pending = [];
for (var i = number; i > 0; i--) {
pending.Push(currentDate - (87677*i));
}
return pending;
};
});
Je cherche des informations et découvre le service $q.all()
mais je ne parviens pas à le faire fonctionner comme je le souhaite.
Tous les conseils seraient les bienvenus! Merci!
Vous pouvez utiliser $ q.all pour attendre la fin de plusieurs événements ansynchrones (promesses).
$scope.ticket_stats = function() {
// list of all promises
var promises = [];
//cleaning variables
$scope.data_set = [];
$scope.closed_tickets = [];
//fetching time stamps (Epoch)
$scope.time_frame = time_period.days(7);
//calling data using time stamps
angular.forEach($scope.time_frame, function(item) {
// create a $q deferred promise
var deferred = $q.defer();
//debug
console.log(item);
tickets.status("closed", item).success(function(data) {
console.log(data);
$scope.closed_tickets.Push(data[0].datapoints[0][0]);
// promise successfully resolved
deferred.resolve(data);
});
// add to the list of promises
promises.Push(deferred.promise);
});
// execute all the promises and do something with the results
$q.all(promises).then(
// success
// results: an array of data objects from each deferred.resolve(data) call
function(results) {
$scope.data_set.Push($scope.closed_tickets);
},
// error
function(response) {
}
);
}
Tout d’abord, deferred
représente un morceau de code dont l’exécution (asynchrone) prendra un temps inconnu. deferred.resolve(data)
indique simplement que le code est terminé. Les données peuvent être n'importe quoi, un objet, une chaîne de caractères, mais ce sont généralement les résultats de votre code asynchrone. De même, vous pouvez rejeter une promesse avec deferred.reject(data)
(peut-être qu'une erreur a été émise par le serveur). Encore une fois, les données peuvent être n'importe quoi mais ici, ce devrait probablement être la réponse d'erreur.
deferred.promise
renvoie simplement un objet de promesse. L'objet de promesse vous permet de définir des callbacks tels que .then(successFunction, errorFunction)
pour que vous sachiez qu'une partie du code a été exécutée avant de passer à successFunction
(ou errorFunction
en cas d'échec). Dans notre cas, $q
a la méthode .all
qui attend qu'un tableau de promesses se termine, puis vous donne les résultats de toutes les promesses sous forme de tableau.
N'oubliez pas d'injecter le service $q
.
Essayez de faire un tableau de promesses seulement, sans les résoudre pour le moment. Puis agrégez-les avec $ q.all (). Après la résolution des promesses agrégées, parcourez à nouveau le tableau de ces promesses. Maintenant, vous êtes sûr qu'ils sont tous résolus.
var promises = [];
angular.forEach($scope.time_frame, function(item) {
promises.Push(tickets.status("closed", item));
});
var aggregatedPromise = $q.all(promises);
aggregatedPromise.success(function(){
angular.forEach(promises, function(promise) {
promise.success(function(data){
$scope.closed_tickets.Push(data[0].datapoints[0][0]); // returns a numerical value
});
});
});
Peut-être que ce n’est pas le moyen le plus efficace de le faire, mais je pense que cela devrait résoudre votre problème.
Même si vous mentionnez que $ q.all n'a pas fonctionné pour vous, car je ne vois pas pourquoi cela ne devrait pas, voici comment je procéderais.
En gros, vous voulez mapper un tableau d'éléments (horodatages) sur d'autres éléments (promesses dans ce cas car nous avons des appels asynchrones) et effectuer des actions sur le tableau résultant.
var promises = $scope.time_frame.map(function (item) {
return tickets.status("closed", item);
});
Nous utilisons maintenant $q.all
pour attendre que toutes les promesses soient résolues:
$q.all(promises).then(function (tickets) {
$scope.data_set.Push(tickets);
});