Adam Adam - 3 months ago 33
AngularJS Question

AngularJS Trigger callback after ForEach

I'm currently developing an AngularJS form which on submit pushes single or multiple participant data to an SQL database.

I'm able to push data to the SQL database, but I'm wanting to trigger a callback that redirects the user once all participant data has been successfully submitted.

At the moment on success it redirects the user but, misses the next foreach submit for the next participant.

Any and all advice would be appreciated.

AngularJS

/* Submit */
$scope.submit = function() {

var array = $scope.form.participants;
//console.log(array);

angular.forEach(array, function(value, key){
var request = $http({
method: "post",
url: 'http://xxx.co.uk/submit.php',
data: {
coachName: $scope.form.program.coachName,
contactArea: $scope.form.program.contractArea,
postcode: $scope.form.program.postcode,
programmeStart: $scope.form.program.programmeDate,
sessionDate: $scope.form.program.sessionDate,
sessionNumber: $scope.form.program.sessionNumber,
weekNumber: $scope.form.program.weekNumber,
id: value.participant.id,
attendance: value.participant.attendance,
weight: value.participant.weight,
goldBehaviours: value.participant.goldBehaviours,
stepCount: value.participant.stepCount,
creditData: value.participant.creditData,
weekOne: value.participant.weekOne,
stepOne: value.participant.stepOne,
weekTwo: value.participant.weekTwo,
stepTwo: value.participant.stepTwo,
weekThree: value.participant.weekThree,
stepThree: value.participant.stepThree,
weekFour: value.participant.weekFour,
stepFour: value.participant.stepFour,
weekFive: value.participant.weekFive,
stepFive: value.participant.stepFive
},
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).success(function(data) {
//console.log(data);
$location.path("/thankyou");
});
});
};


Data

{
"program":{
"coachName":"AD",
"contractArea":"Berkshire",
"postcode":"NN1",
"programmeDate":"2016-08-15T23:00:00.000Z",
"sessionDate":"2016-08-16T23:00:00.000Z",
"sessionNumber":"1",
"weekNumber":"2"
},"participants":[
{"participant":{"id":"AW01","attendance":"Did Not Attend","weight":"1","goldBehaviours":"2","stepCount":"3","creditData":"","weekOne":"4","stepOne":"4","weekTwo":"5","stepTwo":"5","weekThree":"6","stepThree":"6","weekFour":"7","stepFour":"7","weekFive":"8","stepFive":"8"}},
{"participant":{"id":"AW02","attendance":"Attended","weight":"2","goldBehaviours":"3","stepCount":"4","creditData":"","weekOne":"5","stepOne":"5","weekTwo":"6","stepTwo":"6","weekThree":"7","stepThree":"7","weekFour":"8","stepFour":"8","weekFive":"9","stepFive":"9"}}
]
}

Answer

You can inject $q to your controller/service and use $q.all method (you can also use native Javascript Promise if you're not worried about old browsers support).

The all method takes an array of promises and resolve when all promises in the array resolve (it will reject if any of the promises reject).

$scope.submit = function() {

  var array = $scope.form.participants;
  var promises = [];
  //console.log(array);

  angular.forEach(array, function(value, key){
    promises.push($http({
      method: "post",
      url: 'http://xxx.co.uk/submit.php',
      data: {
        coachName: $scope.form.program.coachName,
        ...
        ...
        ...
        stepFive: value.participant.stepFive
      },
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
    }));        
  });
  $q.all(promises).then(function() {
    $location.path("/thankyou");
  });
};