ThomasD
ThomasD

Reputation: 2494

calling angularjs-service iteratively

I have an array of ids and would like to iterate over them and pass them to a service to fetch some data. But I would like to only move to the next id after the processing of the previous id has finished. After all the data has been fetched I need to call a specific function.

My code (without the iteration) wold be something like

MyService.fetch(id)
        .success(function (data, status, headers, config) {
            doSomething();
        });

What I want to achieve is something like this but in a way which can handle an unknown number of items in my array of ids:

MyService.fetch(id).success(function (data, status, headers, config) 
{
   MyService.fetch(id2).success(function (data, status, headers, config) 
   {
     doSomething();
   });
});

Any ideas how to achieve this ?

thanks

Thomas

Upvotes: 1

Views: 95

Answers (3)

null
null

Reputation: 7926

Angular comes with a lite promise library: $q. It's actually quite simple to do.

Service

myApp.factory('theProcessor', function($q, $timeout) {

  return {
    fetch: function(queue, results, defer) {

      defer = defer || $q.defer();

      var self = this;  

      // Continue fetching if we still have ids left

      if(queue.length) {

        var id = queue.shift();

        // Replace this with your http call
        $timeout(function() {
          // Don't forget to call d.resolve, if you add logic here 
          // that decides not to continue the process loop.
          self.fetch(queue, results, defer);
          results.push({ id: id, value: Math.floor((Math.random()*100)+1) });
        }, 500);

      } else {

        // We're done -- inform our caller 
        defer.resolve(results);
      }

      // Return the promise which we will resolve when we're done
      return defer.promise;
    },
  };

});

See it in action at this plunker.

Upvotes: 3

Kia Raad
Kia Raad

Reputation: 1335

You could use the $q's all() method to bundle all the promises that you define and then do something after all of them are resolved e.g:

$q.all([promise1, promise2, ...]).then(...)

You may want to consider implementing this feature in your controller or your service.

Take a look at HERE for a complete API reference and details.

UPDATE

Just thinking that your service could accept an array of ids and it could have a method which would recursively fetch the data in order that you want. Look and the following code, it's an idea so it may not work as is:

function(){
    var result = [];
    var fetch = function(idArr /*this is your ID array*/){

          (a simple guess if what you want to do with that ID)
          $http.get('yourURL?id=' + <first element of idArr>)
            .success(function(data){
                //some logic
                result.push(data);
                idArr.splice(1,0);
                fetch(idArr);
            });
    }
}

Upvotes: 1

user2445933
user2445933

Reputation:

Try to use following approuch:

var idsArray= [], result = [];

/// ...After filling array

function nextIteration(index) {
   MyService.fetch(idsArray[index]).success(function (data, status, headers, config)
   {
      result.push(data);
      if (++index < idsArray.length) {
         nextIteration(index)
      } else {
         console.log('Task complete');
      }
}

nextIteration(0);

Upvotes: 2

Related Questions