1

I have this API call, but I don't receive the data in my successCallback in the same order as I send it.

    for (var i = 0; i < data.length; i++) {
      $http.post('/api/bla/blabla', $.param(data[i]))
        .then(successCallback, errorCallback);
     }

    var successCallback = function (response) {
       /*
       receive data in random order.
       assume its being send / handled so fast, thats its random
       which gets done first.
       */
    };

Can I somehow wait for all data to be received, and then reorder it to the original ordering? or is there another solution.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Anders Pedersen
  • 2,255
  • 4
  • 25
  • 49
  • 1
    You could do this, but it would be *much, much* easier to just send all data in a single request. – Rory McCrossan Apr 08 '16 at 10:00
  • 1
    see this question http://stackoverflow.com/questions/21310964/angularjs-q-all you can use $q.all to execute code once all your promises are resolved – Groben Apr 08 '16 at 10:02
  • The backend I'm working with does not support that :/ needs to receive it one at a time. – Anders Pedersen Apr 08 '16 at 10:02
  • it would still receive one at a time, it's just that the callback would be called once all request have ended – Groben Apr 08 '16 at 10:07

3 Answers3

6

Use $q.all to get all the data in the right order.

var promiseArray = [];
for (var i = 0; i < data.length; i++) {
    var dataPromise = $http.post('/api/bla/blabla', $httpParamSerializer(data[i]))
        .then (function (response) {
             //return data for chaining
             return response.data;
        })
    ;
    promiseArray.push(dataPromise);
}

$q.all(promiseArray).then(function (dataArray) {
     //dataArray will be in original order
     //process results here
}).catch (function (errorResponse) {
     //log error
});

The promiseArray will be created in the correct order. Even though the individual XHR POST requests may not be served in the original order, the $q service will track the promises and fill the data array in the correct order (or resolve rejected on the first error).

The DEMO on JSFiddle.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • Are you sure `dataArray` will be in the same order? Surely it will be in the order the server responded to the requests, which is not guaranteed to be the same order the requests were sent in. – Rory McCrossan Apr 08 '16 at 10:25
  • The `promiseArray` is created immediately in the correct order. Even though the individual promises may be fullfilled in a different order, their position in the `promiseArray` stays the same. `$q.all` waits for fulfillment of all the individual promises. The `dataArray` resolves in the same order as the `promiseArray`. – georgeawg Jul 28 '16 at 03:07
0

As Groben says, you could create an array of the promises for each request, and then you can use the "when" callback to execute when all are completed.

John Mc
  • 2,862
  • 1
  • 22
  • 37
  • would you mind typing this out in an example preferable in my specific case ? would really help. – Anders Pedersen Apr 08 '16 at 11:02
  • The answer by @georgeawg above is exactly what I am suggesting. Instead of "when" he uses "then", which is probably more correct – John Mc Apr 08 '16 at 11:05
0

$http.get('/someUrl', config).then(successCallback, errorCallback); $http.post('/someUrl', data, config).then(successCallback, errorCallback); you can try these note the The response object has these properties:

data – {string|Object} – The response body transformed with the transform functions.
status – {number} – HTTP status code of the response.
headers – {function([headerName])} – Header getter function.
config – {Object} – The configuration object that was used to generate the request.
statusText – {string} – HTTP status text of the response.

And these too can also work depending on the API you working on...