Search code examples
jqueryangularjsajaxdeferred

wrap jquery when around angular data service calls within loop


So I have a page that upon an action needs multiple ajax calls. The angular dataService.getData is called which uses $q/deferred like so:

return {
    getData: function(obj) {
        var def = $q.defer();

        $http({
            url: obj.url,
            method: "GET",
            headers: { "Content-Type": "application/json" }
        }).then(function(data) {
              if (data.data) {
                  def.resolve({
                     response: data 
                  })
              }
        })
        return def.promise;
    }
}

at one point I need to call a few individual requests on a group of items from the controller:

$scope.goGetEmBoys = function(group) {
    config.group.forEach(function(d) {
         if(d.name == group) {
             dataService.getData({url: d.urlToCall})
                 .then(function(data){
                       // use each with its own registered callback
                       d.callback(data);
                 })
         }
    })
}

What I want to do is have a bitValue to toggle when requests are working and when completed, even if I have to store something like $scope.somethingIsHappening = 0, etc

I think wrapping it in the $.when deferred reads like a reasonable approach but I have been unable to get that working, also is there a better approach to this versus trying to fit the call (goGetEmBoys function and ultimately the loop) inside a deferred like this?

tried the call to the scope function, as well as the block within it inside a jquery when....I must be using it wrong. Any advice is welcome.


Solution

  • I don't know I fully understood what do you want to achieve - you want to know when all request are completed? If length of group does not change, you may try the following:

    $scope.areReqestsFinished = false;
    $scope.goGetEmBoys = function(group) {
        var counter = 0;
        config.group.forEach(function(d) {
             if(d.name == group) {
                 dataService.getData({url: d.urlToCall})
                     .then(function(data){
                           // use each with its own registered callback
                           d.callback(data);
                           counter++;
                           if (counter === config.group.length) {
                               $scope.areRequestFinished = true; 
                           }
                     })
             }
        })
    }
    

    And you can set up a $scope.$watch on $scope.areRequestFinished to act when requests are finished. You can also play with $q.all but I never made it working for me, also I think my solution is quite easy to figure it out, even if it requires more code. Watch can be like this:

    $scope.$watch('areRequestFinished', function (newValue, oldValue) {
        if ((newValue !== oldValue) && (newValue === true)) {
            doSomething();
        }
    });