Search code examples
javascriptparse-platformpromiseparse-cloud-code

Parse: Query.find does not find data inside loop (even after using promises)


I am actually passing two lists(existingLeaderboard and newResultSetObj) and i am comparing and querying them according to some logic. In the last i want to send notification to each user according to logic. But somehow my code does not wait for the find query(console log never shows up in the logs).Here is the code -

function compareAndSendNotification(existingLeaderboard, newResultSetObj) {
        var _ = require('underscore');
        var leadboardarray=[];
        console.log("New leaderboard" + newResultSetObj);
        console.log("Existing leaderboard" + existingLeaderboard);
        leadboardarray = existingLeaderboard;


        if (typeof existingLeaderboard == "undefined" || typeof newResultSetObj == "undefined"
            || existingLeaderboard.length == 0 || newResultSetObj.length == 0) {
            console.log("existingLeaderboard or newResultSetObj is null");
            return true;
        }

        var getUserFromLookPromise = Parse.Promise.as();

            var fromUser = "";
            //Event out looks


            _.each(existingLeaderboard, function(test) {
                if (contains(newResultSetObj, test)) {
                    console.log("Look id still in top 3 i =" + test);
                    // get user from look
                    var lookId = test;
                    console.log('get look id called ' + lookId);

                    var look = Parse.Object.extend("Look");
                    var lookQuery = new Parse.Query(look);
                    lookQuery.equalTo("objectId", lookId);

                    console.log("before find query");

                    //getUserFromLookPromise=getUserFromLookPromise.then(function(){
                    //     return lookQuery.find();
                    lookQuery.find().then(function(){
// following console log never prints 
                        console.log("inside find query");
                        var lookqueryPromise = Parse.Promise.as();
                        lookqueryPromise = lookqueryPromise.then(function() {
                            return lookQuery.find();
                        });
                        //while(lookqueryPromise.find().length==0){
                        //    lookqueryPromise.resolve(lookQuery.find());
                        //}
                        return lookqueryPromise;

                    }).then(function (notificationUser) {
                        console.log("inside resolve user");
                        if ( typeof notificationUser == "undefined" || notificationUser.length == 0 ) {
                            getUserFromLookPromise.resolve(notificationUser);
                        }
                        fromUser = notificationUser[0].get['fromUser'];
                        return fromUser;
                    }).then(function (user) {
                        console.log("sending notification to user " + user);
                        sendNotification(user, "hello");
                    });


                }
            });

        return getUserFromLookPromise;

    }

I am new to parse. Please let me know what i am doing wrong.


Solution

  • Lets start with a smaller problem: Get a "Look" object given its id:

    function lookWithId(objectId) {
        var query = new Parse.Query("Look");
        query.include("fromUser");  // presumes "fromUser" is a pointer to Parse.User
        return query.get(objectId);
    }
    

    Now, lets use that function to solve a bigger problem: Get an array of "Look" objects given an array of ids:

    var _ = require('underscore');
    
    function looksWithIds(objectIds) {
        var promises = _.map(objectIds, function(objectId) {
            return lookWithId(objectId);
        });
        return Parse.Promise.when(promises);
    }
    

    Now a tougher one. Given an array of users, send each one a message. This can be done only if your app associates Installations with Users by setting up a "user" pointer on each installation.

    function sendMessageToUser(user) {
        var query = new Parse.Query(Parse.Installation);
        query.equalTo('user', user);
        return Parse.Push.send(where: query, data: { alert: "Hello" });
    }
    

    And pluralize that one as we did before...

    function sendMessagesToUsers(users) {
        var promises = _.map(users, function(user) {
            return sendMessageToUser(user);
        });
        return Parse.Promise.when(promises);
    }
    

    One more function that you write: Given two leaderboards, return an array of "Look" object ids that meet some app criteria...

    function lookIdsFromLeaderBoards(leaderBoardA, leaderBoardB) {
      // written by @user2922400, based on the app
      // no promises needed here, just answer an array of Look object ids
    }
    

    Now, the function you were attempting is as easy as pie:

    function sendMessagesToLeader(leaderBoardA, leaderBoardB) {
        var lookIds = lookIdsFromLeaderBoards(leaderBoardA, leaderBoardB);
        return looksWithIds(lookIds).then(function(lookObjects) {
            var users = _.map(lookObjects, function(lookObject) {
                return lookObject.get("fromUser");
            });
            return sendMessagesToUsers(users);
        })
    }