Promises array


#1

i am new to ionic framework and promises, this is part of my factory, Productos

....
    },                     
        getCombinations: function(productId) {
                var resultt = [];
                var promises = [];
                url_to = 'http://example.com/api/combinations?display=full&filter[id_product]=' + productId;
                $http({method: 'GET', url: url_to })
                        .then(function(response) {
               results = x2js.xml_str2json(response.data);
               angular.forEach(results.prestashop.combinations.combination, function(val, key) {
                                   var deferred = $q.defer();
                   url_to = 'http://example.com/api/product_option_values?display=[name,color]' + '&filter[id]=[' + val.associations.pr
oduct_option_values.product_option_value[0].id + '|' + val.associations.product_option_values.product_option_value[1].id + ']';
                   $http({method: 'GET', url: url_to }).then(function(response) {
                                        results = x2js.xml_str2json(response.data);
                                        resultt.push({ 'size': results.prestashop.product_option_values.product_option_value[0].name.la
nguage.__cdata, 'color_hex': results.prestashop.product_option_values.product_option_value[1].color.__cdata, 'color_name': results.pres
tashop.product_option_values.product_option_value[1].name.language.__cdata}); 
                                        deferred.resolve(resultt); 
                   })          
                   promises.push(deferred);
               });         
           }, function(response) {
                   return $q.reject(response.data);
                   //something went wrong
           });             
        return $q.all(promises);
          },               
....

and in my controller

...
          Productos.getCombinations(productId) 
                    .then(function(data) {    
            console.log('getcombinations');
            console.log(data);
...

but my data is empty, could someone help me out, thanks in advance.


#2

Hey there,

  1. if you want to add a function that returns a promise -> this function has to return the promise object like deferred.promise

  2. to get the response of all promise tasks you have to call $q.all(promises).then(succCallback, errCallack);

    function promiseFunction() {
    var defer = $q.defer();
    if (bla) {
    defer.resolve();
    } else {
    defer.reject();
    }
    return defer.promise;
    }
    $http(…).then(function (data) {
    var promises = [];
    promises.push(promiseFunction());
    $q.all(promises).then(successCall, errCall);
    });

In your case you are sending another request in “promiseFunction”.
You are expecting a promise in your controller, so you have to return a promise also in your first request like that:

var requestPromise = $q.defer();
$http(...).then(function (data) {
      var promises = [];
      promises.push(promiseFunction());
      $q.all(promises).then(requestPromise.resolve, requestPromise.reject);
});

And keep in mind you have to pass your responds value in promise.resolve :wink:


#3

i changed to promises.push(deferred.promise); with no avail.

could you elaborate with my example please, i dont understand your aswer.


#4

changed resultt to resultt = {'size': results.prestashop.product_option_values.product_option_value[0].name.language.__c....

and

 promises.push(deferred) instead of promises.push(deferred.promise)

if i do:

var oeee = $q.all(promises);
console.log(oeee); 

shows me:

[Object { promise={...}, resolve=function(), reject=function(), más...}, Object { promise={...}, resolve=function(), reject=function(), más...}, Object { promise={...}, resolve=function(), reject=function(), más...}, Object { promise={...}, resolve=function(), reject=function(), más...}, Object { promise={...}, resolve=function(), reject=function(), más...}, Object { promise={...}, resolve=function(), reject=function(), más...}, Object { promise={...}, resolve=function(), reject=function(), más...}, Object { promise={...}, resolve=function(), reject=function(), más...}, Object { promise={...}, resolve=function(), reject=function(), más...}]

so it seems its a fine promise array.
what do i do with it?


#5

If this is your request function:

$q.all(promises).then(function (data) {
  //success callback
}, function (err) {
  // error callback
});

For this (succes, error) you should use another promise to say your caller of this request - "hey there everything has finished successfully.
And then you can do something like that in your controller:

myRequestService.doRequest(params).then(function (respsonse) {
   // correct response data of the request
}, function (err) {
   // error handling like error message
});

Here you have an example with your code of the first post:

And you should think about performance, if you get a bunch of repsonse items do not use angular.forEach. The ordinary javascript for-loop is the fastest one ;).


#6

thank you for your efforts, i put the same stuff but at the end the same happened, it executed way later than i needed, so my variables wasnt set.

at the end kind of a hack but i need to get it done, later with more time i will look at this , or when i get more knowledge of this great angularjs ionicframework.

i did this at the end:

       $scope.$watch('combinations', function(newVal) {
                          if ( $scope.combinations.length != 0 )
                          {
                                        angular.forEach($scope.combinations, function(val, key) {
                                                if ($scope.sizes.indexOf(val.size) == -1) {      
                                                         $scope.sizes.push(val.size);      
                                                }                                    
                                        });                             
                                            
                                        /*TODO: make colors unique */
                                         angular.forEach($scope.combinations, function(val, key) {
                                                         $scope.colors.push({'color_name': val.color_name, 'color_hex': val.color_hex }
);
                                        }); 
                          };                

    });

#7

You can build a codepen or a real example with this.
I would help you :wink: