Sidharth Sethia
Sidharth Sethia

Reputation: 79

How to make queries in loop using Parse promises in cloud code?

The response received is always an empty array. The inner stands_query in the for loop never gets executed. Also I would like to know if there is again an inner query inside the stands query then how do I achieve that. STANDS CLASS STADIUMS CLASS Code below :

var final_list = [];
query.find().then(function(stadiums){
    _.each(stadiums,function(stadium){
        var stands_query = new Parse.Query(“Stands");
        stands_query.equalTo(“stdId”,stadium.get(“stdId"));
        var promise =  stands_query.find().then(function(stands){
             _.each(stands,function(stand){
                  var jsonObject = {
                      “stdId": stand.get(“stdId").id,
                   }
                   final_list.push(jsonObject);
             });
             return null;
        },function(error){
             return response.error(error);
        });
        return promise;
       });
 }).then(function(){
    response.success(final_list);
 });

Upvotes: 0

Views: 735

Answers (2)

danh
danh

Reputation: 62676

We have many Stadiums, and every stadium has many Stands. The relationship between Stadium and Stand is represented in data by a pointer column on the Stands class called "stadiumId".

In comments, the functional goal is stated very simply: a JSON array of stands. This requires a single query, no looping at all:

function allTheStands() {
    var query = new Parse.Query("Stands");
    query.include("stadiumId");
    return query.find().then(function(stands) {
        return JSON.stringify(stands);
    });
}

// call it like this:
allTheStands().then(function(jsonStands) {
    // jsonStands is all of the stands represented as son
});

EDIT

A more roundabout way to the same result is to not include stadiumId in the query, instead doing a fetch after the stands query completes.

(This is just a specific form of advice given by @adamdport, given details of your data. You should credit his answer if you find this useful).

// adding underscorejs for handling arrays and other utils
var _ = require('underscore');

function allTheStands() {
    var stands;
    var query = new Parse.Query("Stands");
    return query.find().then(function(result) {
        stands = result;
        // we're not done yet, because we need to fetch each stand's stadium
        var promises = _.map(stands, function(stand) {
            return stand.get("stadiumId").fetch().then(function(stadium) {
                stand.set("stadiumId", stadium);
            });
        });
        // as adamdport suggests, the crux of the looping answer is to use Promise.when()
        return Parse.Promise.when(promises);
    }).then(function() {
        return JSON.stringify(stands);
    });
}

Upvotes: 1

adamdport
adamdport

Reputation: 12613

Your first .then isn't returning anything. I'll break your code down so you can see it:

query.find().then(function(stadiums){   //anonymous function 1
  _.each(stadiums,function(stadium){    //anonymous function 2
    return "foo" //this returns "foo" as a result of anonymous function 2.
  });
  //Nothing explicitly returned from function 1!
}).then(function(){
  response.success(final_list);
});

A function that lacks an explicit return statement will return undefined. Your code then executes "response.success" before any of the internal promises resolve.

What you could do instead is create an array of internal promises that you wait for with Parse.Promise.when:

query.find().then(function(stadiums){
  var promises = [];
  _.each(stadiums,function(stadium){
    var promise = stands_query.find().then(...)
    promises.push(promise);
  });

  //if returning another promise, the ".then" won't execute until it completes.
  return Parse.Promise.when(promises); 
}).then(function(){
  response.success(final_list);
});

All this being said, you may run into timeout issues depending on how large your dataset is. Consider rewriting your query so that you query for Stands belonging to a Stadium with relational queries instead.


Update

Now that you've updated your question with fields, it looks like your line stands_query.equalTo(“stdId”,stadium.get(“stdId")); has two mistakes and will never return results. It should be stands_query.equalTo(“stadiumId”,stadium);.

Upvotes: 1

Related Questions