0

I just can't seem to get a hang of JavaScript promises.

In Parse, I have an attribute on a user that stores an array of Facebook friends IDs. When a new user logs in through Facebook for the first time I want to iterate through their Facebook friends that are using the app, then update those user's Facebook friends array to include this new user.

So... in user before_save I have this:

var friendsArray = user.get("facebookFriends");
// Iterate through all Facebook friends
_.each(friendsArray, function(facebookId){

   // Retrieve the Facebook friend user 
   var query = new Parse.Query(Parse.User);
   query.equalTo("facebookId", facebookId);

   console.log("this executes");
   query.find().then( function(){
       var user = results[0];
       // This does not execute
       console.log("Need to update " + user.get("displayName") + "'s facebook friends");
       return Parse.Promise.as();
   });
}

My problem is not that different than another previous problem I encountered (Parse JavaScript SDK and Promise Chaining), except that this time I need the results of the async call before I can begin updating the user's Facebook friends array.

3
  • 1
    wow, that title was misleading... Commented Feb 15, 2015 at 5:32
  • @irrational Can you offer some suggestions on how to improve the title? Commented Feb 15, 2015 at 5:46
  • 1
    @Todd Parse JavaScript SDK is a very specific library with its own complex behavior, and familiarity with it is required to answer this question, so I'd suggest it would probably be helpful to mention it in the question title. Commented Feb 15, 2015 at 5:53

1 Answer 1

1

The way to accomplish this is with Parse.Promise.when() which is fulfilled when array of promises passed to it are fulfilled. And the loop can be made prettier as _.map().

var friendsArray = user.get("facebookFriends");
var findQs = _.map(friendsArray, function(facebookId){

    // Retrieve the Facebook friend user 
    var query = new Parse.Query(Parse.User);
    query.equalTo("facebookId", facebookId);

    console.log("this executes");
    return query.find();
});

return Parse.Promise.when(findQs).then(function(){
    var user = results[0];
    // This will work now
    console.log("Need to update " + user.get("displayName") + "'s facebook friends");
    return Parse.Promise.as();
});

The results will be an array of arrays -- since find returns an array --passed as var-args, and underscore _.toArray() is useful here, i.e.

return Parse.Promise.when(finds).then(function() {
    var individualFindResults = _.flatten(_.toArray(arguments));
    // and so on
Sign up to request clarification or add additional context in comments.

4 Comments

It's not immediately obvious why you might need to flatten the args?
@Roamer-1888, find() returns an array of matches, so the args will be an array of arrays. This might be desirable in some cases, but not in the OP.
Thanks! It works, but I guess I don't really understand why mine didn't work.
Your code tries to start several queries from a loop. The loop completes before all of the queries have. Sometime soon after the loop your code finishes executing , never giving the remaining queries a chance. When() keeps the execution context around until all promise passes to it are fulfilled.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.