0

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);
 });
6
  • Please describe the data. Easiest way is to post an snapshot of the top row of the data browser for Stadium and Stand objects. Commented Dec 12, 2015 at 0:43
  • A stadium has many stands. The first query return all the stadiums. Then for each stadium I need the id's of all the stands. The second query returns me all the stands of that stadium. Then I make a JSON object of id of each stands and push it into final_list @danh Commented Dec 12, 2015 at 20:46
  • Please post a snapshot of the top row of the data browser. Need to know names and types of the pertinent columns. Commented Dec 12, 2015 at 20:51
  • I have added the screenshots @danh Commented Dec 12, 2015 at 21:06
  • Good, thanks. I get the data now. Now how about the objective? A JSON array of Stadiums? And do we want the Stadiums to have an array of Stands? This is important: do we want parse objects back or JSON representation of regular JS objects? Hint in your code is that you want the latter (in other words, no id, or createdAt or updatedAt or ACL, etc etc). Commented Dec 12, 2015 at 21:21

2 Answers 2

1

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);.

Sign up to request clarification or add additional context in comments.

3 Comments

This is good advice, though tough to give clearly without understanding the OP's data. A slightly prettier variation generates the promise array by _.map()-ing over stadiums.
I tried the above code. I am still receiving an empty array
To be clear, the OP wants an array of all stands with the stadium pointers resolved. (Not what one would expect, I admit. I too expected at some point to be qualifying a stands query given a stadium. But this seems not to be the goal).
1

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);
    });
}

4 Comments

I got the answer this way but I also want to know how to perform query inside a loop using promises as done in the question since I have a similar situation in my another cloud function and it is also returning an empty array
One might argue that your similar situation could be simplified in this manner as well :) If your app grows even modestly, you will want to reduce the number of queries both for performance and since each one counts towards the requests/second that Parse bills you for.
@danh Your edit confused me. Even if you called stand.save (which is missing), you're not making any changes to it. What are you trying to accomplish with promises?
Sorry to hear. I thought we clarified in comments that the objective was to answer JSON representation of stands. No alteration or save() of stands is called for. The set in the code is there to replace the pointer (to stadium) with the fetched stadium (the same stadium except with all of its attributes fetched).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.