Is it possible to do nested queries in cloud code?
I want to be able to do something like
var adList = [];
var query2 = new Parse.Query("QR");
var query = new Parse.Query("Campaigns");
query.equalTo("isFeatured", true);
query.find({
success: function(results)  {
    for (var i=0; i<results.length; i++){
        var ad = [];
        ad.push(results[i].get("Type"));    //Adds "Type" to the ad array
        ad.push(results[i].id);     //gets the objectID and appends it to the arrayy
          //second INNER QUERY
        query2.equalTo("abc", true);
        adList.push(ad);
        query2.first({
            success: function(results){
                adList.push(5);
            },
            error: function(){
                response.error("inner fail");
            }
        });
    }
    response.success(adList);  //adds all ad arrays to adList array
},
error: function(){
    response.error("failed");
}   
});
I tried doing this, but the inner query never executes. Why?
The second query is asynchronous so wrapping it in a for won't work.
response.success gets triggered before the second query finished so you are returning before actually waiting for the results. I would tell you to move response.success inside of the second success callback of query2 but that won't work either since you are running an async operation synchronously inside a for so you will send the response in the first success.
Don't run an async operation inside a loop. It doesn't work.
I'm not sure what you are trying to accomplish here but you'll have to instantiate a new Query for every call if you want to make as many queries as results.
Again, I'm not sure what is exactly you are trying to do but here is a way you can do something like that:
    var adList = [];
    var query = new Parse.Query("Campaigns");
    query.equalTo("isFeatured", true);
    query.find({
        success: function(results)  {
            var queries = [];
            for (var i=0; i<results.length; i++){
                var query2 = new Parse.Query("QR");
                query2.equalTo("abc",true);
                var ad = [];
                ad.push(results[i].get("Type"));
                ad.push(results[i].id);
                adList.push(ad);
                queries.push(query2);
            }
            var totalLength = results.length;
            function makeQueries(qs){
                qs.shift().first({
                    success: function(currentResult) {
                        // do stuff with currentResult
                        if(qs.length){
                            makeQueries(qs);
                        } else {
                            console.log('We successfully made ' + totalLength + ' queries')
                            // we are done with the queries
                            response.success(adList);
                        }
                    },
                    error: function() {
                        response.error('Error in inner queries nº' + totalLength - qs.length)
                    }
                });
            }
            makeQueries(queries);
        },
        error: function(){
            response.error("failed");
        }
    });
Bar in mind that Parse Cloud Code let you run code for aprox 5/7 seconds and this might be very slow if you have a lot of results.
Btw, take a look a Parse's matchesQuery method.
Example taken from their docs:
    var Post = Parse.Object.extend("Post");
    var Comment = Parse.Object.extend("Comment");
    var innerQuery = new Parse.Query(Post);
    innerQuery.exists("image");
    var query = new Parse.Query(Comment);
    query.matchesQuery("post", innerQuery);
    query.find({
      success: function(comments) {
        // comments now contains the comments for posts with images.
      }
    });        
                        I think the below code might help someone,
var adList = [];
var query2 = new Parse.Query("QR");
var query = new Parse.Query("Campaigns");
query.equalTo("isFeatured", true);
query.find().then(function(results) {
    var _ = require('underscore');
    var promise = Parse.Promise.as();
    _.each(results, function(resultObj) { 
        var ad = [];
        ad.push(resultObj.get("Type"));    //Adds "Type" to the ad array
        ad.push(resultObj.id);     //gets the objectID and appends it to the arrayy
        //second INNER QUERY
        query2.equalTo("abc", true);
        adList.push(ad);
        return query2.first().then(function(results) {
            adList.push(5);
        });
    });
    return promise;
}).then(function() {
    response.success(adList);
}, function (error) {
    response.error("Error "+error.message);
});
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With