Jayson Lane
Jayson Lane

Reputation: 2828

Parse Nested Promises?

I'm attempting to look up users who have phone numbers matching those in the input array. However, I believe response.success(friends); is being called before the userQuery is complete. With my current data this should return 2 users, however, as it is currently written it returns only an empty array. If I put the success response inside of the userQuery (simply to test), I get a user back so I know the query is right. Do I need another nested promise?

Parse.Cloud.define("addFriends", function(request, response) {
    var _ = require('underscore.js');
    Parse.Cloud.useMasterKey();

    var friends=[];

    var theNumbers = request.params.phoneNumbers;
    var userId = request.params.user;


    var currentUserQuery = new Parse.Query("User");
    currentUserQuery.equalTo("objectId", userId)
    currentUserQuery.first().then(function(currentUser) {
        var promise = Parse.Promise.as();


        _.each(theNumbers, function(aNumber) {
            promise = promise.then(function() {
                console.log('looking for: ' + aNumber);

                userQuery = new Parse.Query("User");
                userQuery.equalTo("phoneNumber", aNumber);
                userQuery.first().then(function(foundUser){
                    console.log("Found user: " + foundUser);

                    friends.push(foundUser);
                });
            });

            return promise;
        });
    }).then(function(){
        console.log('done');
        response.success(friends);
    });
});

Upvotes: 1

Views: 640

Answers (2)

wayne
wayne

Reputation: 3410

add all the sub promises into an array friend, return a new promise with Parse.Promise.when. The response.success need to return arguments because Parse.Promise.when return one result per argument rather than array.

Parse.Cloud.define("addFriends", function(request, response) {
    var _ = require('underscore.js');
    Parse.Cloud.useMasterKey();

    var friends=[];

    var theNumbers = request.params.phoneNumbers;
    var userId = request.params.user;


    var currentUserQuery = new Parse.Query("User");
    currentUserQuery.equalTo("objectId", userId)
    currentUserQuery.first().then(function(currentUser) {


        _.each(theNumbers, function(aNumber) {
            console.log('looking for: ' + aNumber);

            userQuery = new Parse.Query("User");
            userQuery.equalTo("phoneNumber", aNumber);
            friends.push(userQuery.first());
        });
        return Parse.Promise.when(friends);
    }).then(function(){
        console.log('done');
        response.success(arguments);
    });
});

Upvotes: 1

Jesse the Game
Jesse the Game

Reputation: 2630

You'll need to return the promise in order to make the next .then call wait until it's resolved.

Parse.Cloud.define("addFriends", function(request, response) {
    var _ = require('underscore.js');
    Parse.Cloud.useMasterKey();

    var friends=[];

    var theNumbers = request.params.phoneNumbers;
    var userId = request.params.user;


    var currentUserQuery = new Parse.Query("User");
    currentUserQuery.equalTo("objectId", userId)
    currentUserQuery.first().then(function(currentUser) {
        var promise = Parse.Promise.as();


        _.each(theNumbers, function(aNumber) {
            promise = promise.then(function() {
                console.log('looking for: ' + aNumber);

                userQuery = new Parse.Query("User");
                userQuery.equalTo("phoneNumber", aNumber);
                userQuery.first().then(function(foundUser){
                    console.log("Found user: " + foundUser);

                    friends.push(foundUser);
                });
            });

            return promise;
        });

        // This is where you return the promise, to delay the call to response.success
        return promise;

    }).then(function(){
        console.log('done');
        response.success(friends);
    });
});

Upvotes: 0

Related Questions