0

I'm using Parse Cloud functions for mobile apps, but all of them follow asynchronous nature. Hence to overcome that nature, I started using javascript Promises. But promises also not giving me the desired output.

The problem is : second-then is executed after the third-then. And in third-then the parameter of getRecommendedGroup groups is getting []

getRecommendedGroup(request.params.email, groups, function(data){
    this is a callback
});

Basically groups is an output of 2nd then.

So how should I write my code inorder to make 2nd-then execute before 3rd-then.

Below is the code snippet

Parse.Cloud.define("getGroup", function(request, response) {
            var grpMember = new Parse.Query("GroupMember"),
                groupIds = [],
                groupObj = {};

            grpMember.equalTo("user", request.params.email);
            //from the groupMember we're taking groupId  
            grpMember.find()
                .then(function(grpMemberResponse) {
                    grpMemberResponse.forEach(function(value, index) {
                        var memberObj = value;
                        groupIds.push(memberObj.get("groupId").id);
                    });
                    return groupIds;
                })
                //with this groupId we're retriving group and pushing it to an groupArr
                .then(function(groupIds) {

                        var groupArr = [];
                        var promises = [];

                        groupIds.forEach(function(value, index) {
                                alert("GroupId :: " + value);
                                promises.push(findGroup(value, function(group) {
                                        groupArr.push(group);
                                    });
                                });
                            return Parse.Promise.when(promises);
                        })
                    .then(function(groups) {

                        alert("GroupArr :: " + JSON.stringify(groups));
                        getRecommendedGroup(request.params.email, groups, function(data) {

                            groupObj["own"] = groups;
                            groupObj["recommended"] = data;
                            response.success(groupObj);
                        });
                    });
                });

var findGroup = function(objectId, callback) {
    var groupQuery = new Parse.Query("Group");

    groupQuery.get(objectId, {
        success: function(group) {
            alert("Group Obj Id ::" + group.id);
            callback(group);
        },
        error: function(error) {
            alert("Error while finding Group " + error);
        }
    });
};
Tushar
  • 1,115
  • 1
  • 10
  • 26
  • 1
    The `findGroup` is a async function? But even if it is it should not be `undefined` but an empty array `[]`. What Promise library do you use? – t.niese Apr 11 '15 at 11:31
  • yeah..findGroup is also a async function. and sorry for typo it is [ ] and not undefined. And I'm not specifically using any promise library. – Tushar Apr 11 '15 at 11:41
  • Promises are not "overcoming that nature". Promises are *inherently asynchronous*. They just simplify your code by providing an [advanced abstraction over callbacks](http://stackoverflow.com/a/22562045/1048572). – Bergi Apr 11 '15 at 11:52
  • 1
    You have to _return_ promises in order to wait for things – Benjamin Gruenbaum Apr 11 '15 at 12:00

1 Answers1

2

The second then is running second, but it is calling an asynch function. In order to sequence properly, those promises being launched by the loop must be fulfilled. Fortunately, Promise.when() does that...

.then(function(groupIds) {
    var findPromises = []
    groupIds.forEach(function(value, index) {
        findPromises.push(findGroup(value, function(group));
    )};
    return Parse.Promise.when(findPromises);
}).then() {
    // arguments is now a (var arg) array of results from running
    // all of the findPromises promises
});

Edit - In order for this to work, the code needs to push a promise to do the find. That means findGroup must return a promise...

function findGroup(objectId) {
    var groupQuery = new Parse.Query("Group");
    return groupQuery.get(objectId);
}
danh
  • 62,181
  • 10
  • 95
  • 136
  • @dahn I've updated my code as you said, but still the same result – Tushar Apr 12 '15 at 16:47
  • @Tushar2098, please see edit. The `findGroup` function must answer a promise for the caller to push. Promise.when() operates on an array of promises. – danh Apr 12 '15 at 18:36