Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple queries in a loop Parse Cloud Code

I'm having a hard time trying to understand promises, I'm sure I need to use them for this but I don't know how and other answers don't help me at all.

I'd like to loop over an array, query all the results for each value of the array, then after calculating the average value for these results, add the average in an array. After every iterations, this array is sent as a response.

Here is my code which could help understand me here:

Parse.Cloud.define('getScorePeopleArray', function(request, response) {

    var peopleArray = request.params.peoplearray;
    var query = new Parse.Query("Scores");
    var resultat;
    var index, len;
    var resultarray = [];
    var people;

    for (index = 0, len = peopleArray.length; index < len; ++index) {
      people = peopleArray[index];
      query.equalTo("People",people);
      query.find({
        success: function(results) {
          var sum = 0;
          for (var i = 0; i < results.length; ++i) {
           sum += results[i].get("Score");
          }
          resultat = (sum / results.length)*5;
          if(!resultat){
            resultarray.push("null");
          }else{
            resultarray.push(resultat);
          }
        },
        error: function() {
          response.error("score lookup failed");
        }
    }).then();
  }
  response.success(resultarray);  
});

Of course response.success is not called when every queries are done, but as soon as possible (since queries are asynchronous if I'm right). I know I have to change it with promises, but I don't understand at all how this works.

Thanks a lot in advance !

like image 656
Val_Apprem Avatar asked Apr 14 '26 00:04

Val_Apprem


1 Answers

var _ = require('underscore');

Parse.Cloud.define('getScorePeopleArray', function(request, response) {

 var peopleArray = request.params.peoplearray; // what is this an array of?
 var resultArray = [];

  return Parse.Promise.as().then(function() { // this just gets the ball rolling
    var promise = Parse.Promise.as(); // define a promise

    _.each(peopleArray, function(people) { // use underscore, its better :)
      promise = promise.then(function() { // each time this loops the promise gets reassigned to the function below

        var query = new Parse.Query("Scores");
        query.equalTo("People", people); // is this the right query syntax?
        return query.find().then(function(results) { // the code will wait (run async) before looping again knowing that this query (all parse queries) returns a promise. If there wasn't something returning a promise, it wouldn't wait.

          var sum = 0;
          for (var i = 0; i < results.length; i++) {
            sum += results[i].get("Score");
          }
          var resultat = (sum / results.length) * 5;

          if (!resultat){
            resultArray.push("null");
          } else {
            resultArray.push(resultat);
          }

          return Parse.Promise.as(); // the code will wait again for the above to complete because there is another promise returning here (this is just a default promise, but you could also run something like return object.save() which would also return a promise)

        }, function (error) {
          response.error("score lookup failed with error.code: " + error.code + " error.message: " + error.message);
        });
      }); // edit: missing these guys
    });
    return promise; // this will not be triggered until the whole loop above runs and all promises above are resolved

  }).then(function() {
    response.success(resultArray); // edit: changed to a capital A
  }, function (error) {
    response.error("script failed with error.code: " + error.code + " error.message: " + error.message);
  });
});
like image 63
jameswilsterman Avatar answered Apr 16 '26 14:04

jameswilsterman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!