2

In the following cloud code, the first query works fine.

In the chained query, if you include the two lines of code:

query.ascending("createdAt");       // NOTE
query.limit(5);                     // NOTE

it does not work! if you comment out those two lines of code, it works great. What could be the problem?

It throws no errors, but simply does not execute the .each at all. If you comment out the two lines of code in question, the .each executes perfectly for all results found.

Parse.Cloud.define("someFunction", function(request, response)
{
    var query = new Parse.Query("Club");
    query.equalTo("objectId", request.params.club);
    query.first(
    {
        success: function(object)
        {
            return object;
        },
        error: function(error) {...}

    }).then(function(club)
    {
        var query = new Parse.Query("Player");
        query.equalTo("club", club);
        query.include("user");
        query.ascending("createdAt");       // NOTE
        query.limit(2);                     // NOTE
        query.each(function(employee)
        {
            var teste = employee.get("email")
            console.log("teste  ... "  + teste);
        }) ...
danh
  • 62,181
  • 10
  • 95
  • 136
Fattie
  • 27,874
  • 70
  • 431
  • 719
  • related further question for anyone googling here who saw DanH's superb answer below http://stackoverflow.com/questions/32766623 – Fattie Sep 24 '15 at 16:40

1 Answers1

1

I'm surprised it works with our without the sort and limit qualifications. (I don't see how you got to chain .then() off the callback version of first()). The code can be cleaned up and made to work -- I think -- by restricting yourself to the promise-returning variety of the parse methods.

I also recommend factoring into small, promise-returning functions for each logical chunk. With that...

// return a promise fulfilled with a Club object whose id is 'clubId'
function clubWithId(clubId) {
    var query = new Parse.Query("Club");
    return query.get(clubId);  // prettier than "objectId" equalTo and first()
}

// return a promise fulfilled with up to 'limit' Players belonging to 'club' object
function playersWithClub(club, limit) {
    var query = new Parse.Query("Player");
    query.equalTo("club", club);
    query.include("user");
    query.ascending("createdAt"); 
    query.limit(limit);
    return query.find();
}

With these tidy, testable individual parts, we can more confidently build the cloud function as follows...

// a great toolbox for dealing with collections and other stuff
var _ = require('underscore');

Parse.Cloud.define("someFunction", function(request, response) {
    var clubId = request.params.club;
    clubWithId(clubId).then(function(club) {
        return playersWithClub(club, 2);
    }).then(function(players) {
        _.each(players, function(player) {
            var user = player.get("user");
            console.log("username is: " + user.username);
        });
        response.success(players);
    }, function(error) {
        response.error(error);
    });
});

Notice how we get from promise to promise? By returning the object we want as input to the next. Also notice that the chain can have a single rejection function at the end, or intervening ones so long as we follow the rule of returning the results from the resolutions.

danh
  • 62,181
  • 10
  • 95
  • 136
  • You should help this poor padawan also, Dan :) http://stackoverflow.com/questions/31952170/really-confused-re-how-to-use-parse-promises-correctly-in-cloud-code?rq=1 – Fattie Sep 07 '15 at 03:01
  • :-) I had to google "padawan". Looks like the OP solved it, but there's plenty of room to improve the code in that question. – danh Sep 07 '15 at 03:30
  • notice your "response.success" there is the players list. In fact, "why" did you make that the response? Could the response in fact just be (say) a string like "no problems"? (Indeed a response is not actually used in the example at hand, as it happens - it just runs the routine and that's it.) Thx a million... – Fattie Sep 08 '15 at 15:12
  • I try to make my function names agree with the value they return. If this was a procedure (a thing that primarily has a side-effect as opposed to producing an answer), then a name like "doSomething" and response like "done" make sense to me. If it's a true function in the FORTRAN sense, whose job is to compute something, then a name like "playersInClub" and a response of those players would be good. The question here was more about form than function, so I went with your arbitrary name "someFunction" and gave it an arbitrary result. – danh Sep 08 '15 at 15:27
  • That was overly verbose... "success" is a perfectly good response for the function if you don't need any data from it. – danh Sep 08 '15 at 15:28
  • Not overly verbose at all, I utterly and totally understand that. And I completely agree with that naming approach; shame on me for making a lame, ambiguous, name, even as an example name! :O THANKS!!!! – Fattie Sep 08 '15 at 15:38
  • Unnecessarily generous. Thanks! – danh Sep 12 '15 at 21:57