bkellgren
bkellgren

Reputation: 211

Parse.com Cloud job promise with nested query

I have a game on Parse.com where users make submissions and other players vote on them.

I'm trying to write a Cloud background job to update all my user's accounts with vote totals which are the sum of the vote totals from each of their submissions.

I have tried this about 5 different ways and cannot get the nested queries to run (let alone update and save).

Here are the docs and a helpful blog post...

https://parse.com/docs/js_guide#promises-creation

http://blog.parse.com/2013/01/29/whats-so-great-about-javascript-promises/

Here is my latest, any help is greatly appreciated...

Edit: Thanks @axymous for making me see clearly, I needed to explicitly create and immediately return the promise then resolve it in the callback.

Parse.Cloud.job("calculateUserTotals", function(request, status) {
    Parse.Cloud.useMasterKey();
    var query = new Parse.Query(Parse.User);
    query.find().then(function(users) {
        var promises = [];
        _.each(users, function(user) {
            promises.push((function(user){
                var promise = new Parse.Promise();
                console.log(user.toJSON().objectId);  // user objectId is correct here
                var submissionQuery = new Parse.Query('submission');
                submissionQuery.equalTo('user', user.toJSON().objectId);
                submissionQuery.find({  // this doesnt seem to ever run, i have tried .each as well
                    success: function(submissions) {
                        var votes = 0;
                        for (var i=0; i<submissions.length; i++) {
                            var submission = submissions[i];
                            votes = votes + submission.get('votes').length;
                        }
                        user.set('submission_count', submissions.length);
                        user.set('vote_count', votes);
                        user.save({
                            success: function(user) {
                                promise.resolve();
                            }
                        });
                    },
                    error: function(error) {
                        status.error(error);
                    }
                });
                return promise;
            })(user));
        });
        return Parse.Promise.when(promises);
    })
    .then(function() {
        status.success('leaderboard updated.');
    });
});

Upvotes: 2

Views: 2503

Answers (1)

bkellgren
bkellgren

Reputation: 211

I needed to explicitly create and immediately return the promise then resolve it in the callback. Thanks @axymous.

Parse.Cloud.job("calculateUserTotals", function(request, status) {
    Parse.Cloud.useMasterKey();
    var query = new Parse.Query(Parse.User);
    query.find().then(function(users) {
        var promises = [];
        _.each(users, function(user) {
            promises.push((function(user){
                var promise = new Parse.Promise();
                console.log(user.toJSON().objectId);  // user objectId is correct here
                var submissionQuery = new Parse.Query('submission');
                submissionQuery.equalTo('user', user.toJSON().objectId);
                submissionQuery.find({  // this doesnt seem to ever run, i have tried .each as well
                    success: function(submissions) {
                        var votes = 0;
                        for (var i=0; i<submissions.length; i++) {
                            var submission = submissions[i];
                            votes = votes + submission.get('votes').length;
                        }
                        user.set('submission_count', submissions.length);
                        user.set('vote_count', votes);
                        user.save({
                            success: function(user) {
                                promise.resolve();
                            }
                        });
                    },
                    error: function(error) {
                        status.error(error);
                    }
                });
                return promise;
            })(user));
        });
        return Parse.Promise.when(promises);
    })
    .then(function() {
        status.success('leaderboard updated.');
    });
});

Upvotes: 5

Related Questions