1

I am trying to write a loop which performs a number of http requests and adds each response to a list.

However, I don't think I am going about it quite the right way.

I think I am not implementing the required promises correctly. The console log after the for loop shows myList array as empty.

Code:

var _myList = []

function getStuff() {

    var deferred = $q.defer()

    var url = someUrl

    $http.get(url).success(function(response) {

        if ( response.array.length > 0 ) {

            // loop starts here
            for ( var i=0; i < response.array.length; i++ ) {

                getThing(response.array[i].id);

            };
            // check the varibale here

            console.log(_myList);

            deferred.resolve('Finished');

        } else {

            deferred.resolve('No stuff exists');

        };

    }).error(function(error) {

        deferred.reject(error);

    });

    return deferred.promise;

};

function getThing(thindId) {

    var deferred = $q.defer()

    var url = someUrl + thingId;

      $http.get(url).success(function(response) {

            _myList.push(response);

            deferred.resolve(response);

      }).error(function(error) {

            deferred.reject(error);

      });       

    return deferred.promise;

};
2
  • This looks promising, just convert $.ajax to $http Commented Jan 7, 2016 at 18:09
  • Does it matter if they execute in parallel or do you want them to execute in sequence? Commented Jan 7, 2016 at 18:09

2 Answers 2

1

You can simplify your code as follows:

var allThings = response.array.map(function(id){
  var singleThingPromise = getThing(id);
  //return a single request promise
  return singleThingPromise.then(function(){
    //a getThing just ended inspect list
    console.log(_myList);
  })
});
$q.all(allThings).then(function(){
  //only resolve when all things where resolved
  deferred.resolve('Finished');
}, function(e){
  deferred.reject('Something went wrong ' + e);
});
Sign up to request clarification or add additional context in comments.

Comments

1

You indeed won't be able to populate _myList array with for-loop like you set up. Instead create an array of promises - one per data item in response.array and return it as inner promise.

function getStuff() {

    var url = someUrl;

    return $http.get(url).then(function(response) {
        if (response.data.array.length > 0) {
            return $q.all(response.data.array.map(function(data) {
                return getThing(data.id);
            }));
        } else {
            return 'No stuff exists';
        }
    });
}

function getThing(thindId) {
    var url = someUrl + thingId;
    return $http.get(url).then(function(response) {
        return response.data;
    });
}

After that you would use getStuff like this:

getStuff().then(function(myList) {
    console.log(myList);
});

2 Comments

This looks great, won't get a chance to try it until tomorrow, will let you know how it goes. Quick question; is 'return' in this case used instead of deferred.resolve() ?
You should not use deferred for this. $http methods already returns promise, so deferred is redundant (deferred anti-pattern). return from promise creates new promise to be passed down the chain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.