1

In node.js, I have an array of Promises but when I want to execute a Q.all().then(); process, It seems that nothing is happening. Maybe there is an unresolved promise in my array and it blocked the process ? I'm not really sure of what I'm doing here but my goal is to execute all this functions in one time and THEN get back my full "token" array to send it in another file.
How can I do that correctly with Q.all() ?

var pipo = new Array();
var ref_accounts = firebase.database().ref('accounts');
geoQuery.on("key_entered", function(lakey, location, distance) {
    pipo[lakey] = lakey;
});
// I have here my pipo Array full of data
var promises = [];
var token = [];
for (var key in pipo) {
    var deferred = Q.defer();
    var ref = firebase.database().ref("etablissements").orderByKey().equalTo(value).on("child_added", function(snapshot) {
        var data = snapshot.val();
        if ((data.alerte != false) && (data.categorie === categories)) {
            var ref2 = firebase.database().ref("accounts").orderByKey().equalTo(value).on("child_added", function(snapshot2) {
                var data2 = snapshot2.val();
                if (data2.token != null) {
                    token.push(data2.token);
                    deferred.resolve(data2);
                } else {
                    deferred.reject();
                    // or deferred.resolve(); ??
                }
            });
        } else {
            deferred.reject();
            // or deferred.resolve(); ??
        }
    });
    promises.push(deferred.promise);
}

I have my "promises" array full and Now I want here to execute all in once and THEN get all the TOKEN caught in the array

     Q.all(promises).then(function(results) {
       var uniqueNames = [];
       for (i = 0; i < token.length; i++) {
           if (uniqueNames.indexOf(token[i]) === -1) {
               uniqueNames.push(token[i]);
               console.log('tokens' + token[i]);
           }
       },
       // error
       function(response) {
           console.log('Error in then' + response);
       }).catch(function(error) {
       console.log('CATCH ERROR' + error);
   });
   // Send token array to the API
   });

I really don't understand the process. Can you explain me what's wrong with this code please ?

Pablo DelaNoche
  • 677
  • 1
  • 9
  • 28
  • 1
    Your problem is probably related to the for loop. Try extracting the contents of your function block of `for (var key in pipo) ` into a separate function and see if that helps. (google don't create functions in a loop javascript). I recommend using `array.map()` here instead. – Vincent Schöttke Jan 30 '17 at 22:26
  • You'll want to start by adding a .catch() block to capture any errors being outputted. You should additionally log before the Q.all() method is invoked (to make sure the code actually makes it here) and inside .then() (so you know if it ever actually resolves). As a last resort, you'll want to do let count = 0; promises.forEach(() => console.log(++count, 'done')); – Kato Jan 30 '17 at 22:44
  • (Basic debugging due diligence; check all the outputs and isolate the failure point) – Kato Jan 30 '17 at 22:45
  • Thanks @Kato. I edited my question with the .catch() block I did what you said ! I checked all the outputs, everything is fine but I logged "Error in then". So now, I can see where the problem is. How can I resolve this issue ? – Pablo DelaNoche Jan 30 '17 at 23:36
  • And what's the error response? Without knowing that, it's hard to be any more helpful. – Kato Jan 31 '17 at 00:28
  • @Kato Error response is "undefined" ... – Pablo DelaNoche Jan 31 '17 at 10:45
  • 1
    What this means is that one of your promises is calling reject() but not passing in any details. So you'll need to foreach the promises as I mentioned above and find out which one, then dig in there. – Kato Jan 31 '17 at 15:40
  • @bergi this isn't about closures in loops, it's about understanding how Q.all() works and how to troubleshoot specific promise rejections. Although it may very well be a dup, it's not that dup. – Kato Jan 31 '17 at 15:41
  • @Kato Of course it is about the missing closure. If each `deferred` lived in its own scope, and the asynchronous callbacks captured them, the code would work. – Bergi Jan 31 '17 at 15:49
  • @Kato I have 2 promises. With your foreach method I can log '1 done' and '2 done'. So I don't know what to do now ... Everything is fine isn't it ? I tried the "Q.allSettled()" and "Q.all()" method but nothing happened in .then(). Very complicated for me ... Thank you for your help guys. Maybe it is related to the loop and how I resolve or reject promises ? – Pablo DelaNoche Jan 31 '17 at 19:08

1 Answers1

1

I succeed with this :

var pipo = new Array();

was replaced by

var pipo = [];

then I used "async" and used map instead of "forEach"

async.map(pipo, function (item,callback)
{ 
    ...
}); 

Like @Kato said, the error was one of my promises being rejected. I debugged it with this :

let count = 0;
promises.forEach(() => console.log(++count, 'done'));

And in the end, I used Q.all() method with .then() and the most important .catch() !!! Thank you again guys for helping me solving this.

Pablo DelaNoche
  • 677
  • 1
  • 9
  • 28