2

I have been trying to run my Parse Cloud Code for some time and can not seem to get around this problem:

I have an array of Parse objectId's called IDArray. I then am sending the array as a parameter of a PFCloud call. Once the array has been sent to the Cloud Code, I can not seem to successfully create a for loop that goes through and updates a number value stored as "points" on Parse for each objectId.

In a nutshell, this is all I am trying to accomplish:

  • I just need to be able to have the for loop go through each objectId and perform an action for each ID.

I have been trying to get this to work for some time but have had no luck. Here is the code that I have been trying to manipulate - hopefully it will give someone a starting point to answer my question.

Parse.Cloud.define('updateAllUsers', function(request, response) {
    var UserData = Parse.Object.extend('UserData');
    var query = new Parse.Query(UserData);
    var list = request.params.listID;
    var currentuser = request.params.user;

                   
    for (var i = 0; i < list.length; i++) {
                   
        var userdata = list[i];        
        query.get(userdata, {
                                       
            success: function(UserData) {
                               
                response.success('Should add up');
                UserData.addUnique('Done', +1);
                UserData.save();
            },
            error: function() {
                response.error('something went wrong' );
            }
        });
    }
});

If someone could please help me with this I would be very grateful. Thank you

Brennan Casey
  • 887
  • 2
  • 7
  • 17
Will Von Ullrich
  • 2,129
  • 2
  • 15
  • 42
  • What is the value of `request.params.listID` at runtime? And do you go down the `error` path? – Kevin Boucher Aug 13 '15 at 23:49
  • the value of "listID" is an array that contains Parse objectId's. And this is the error that I am receiving in my NSLog: [Error]: Error: Can't call success/error multiple times – Will Von Ullrich Aug 14 '15 at 00:00
  • @KevinBoucher not really sure where to go from here. I have been trying to get this to work using promises, but I cant seem to get it right – Will Von Ullrich Aug 14 '15 at 00:22
  • I think it's because you are using the same `Parse.Query` over and over again. Move the `query` assignment into the loop. – Kevin Boucher Aug 14 '15 at 01:21
  • how would you put the query assignment into the loop? – Will Von Ullrich Aug 14 '15 at 01:23
  • As it stands the code is confusing as the token `UserData` is used twice. The intention behind the code would be clearer if one or other token was renamed. – Roamer-1888 Aug 14 '15 at 13:59
  • well we were really not sure how to even use the cloud code to begin with, so there may be a few errors or statements that don't necessarily make sense. as for the overall process we have still yet to find a solution to accomplish the looping through a list of objectId's and performing an action for each one – Will Von Ullrich Aug 14 '15 at 19:24

1 Answers1

1

I think the problem is you are sending response multiple times, you should wait for all the promises to finish and then send a response:

Parse.Cloud.define('updateAllUsers', function(request, response) {
    var UserData = Parse.Object.extend('UserData');
    var query = new Parse.Query(UserData);
    var list = request.params.listID;
    var currentuser = request.params.user;

    function checkUserData(userdata){   // returns parse promise for a particular userdata
        return query.get(userdata).then(function(){
            UserData.addUnique('Done', +1);
            UserData.save();            
        });
    }

    Parse.Promise.when(list.map(checkUserData)) // mapping all the elements in the list to resp promises
        .then(function(){   // on success
            response.success('Should add up');
        }).catch(function(e){    // on failure
             response.error('something went wrong' );
        });
});

Edit: if for some reason map is not available( in case of older browsers or list not being an normal javascript array), you can do something like:

Parse.Cloud.define('updateAllUsers', function(request, response) {
    var UserData = Parse.Object.extend('UserData');
    var query = new Parse.Query(UserData);
    var list = request.params.listID;
    var currentuser = request.params.user;
    var promises = [];
    function checkUserData(userdata){   // returns parse promise for a particular userdata
        return query.get(userdata).then(function(){
            UserData.addUnique('Done', +1);
            UserData.save();            
        });
    }

    for(var i=0;i<list.length;i++){
        promises.push(checkUserData(list[i]));
    }


    Parse.Promise.when(promises) // once all the promises are resolved...
        .then(function(){   // on success
            response.success('Should add up');
        }).catch(function(e){    // on failure
             response.error('something went wrong' );
        });
});
mido
  • 24,198
  • 15
  • 92
  • 117
  • thanks for your help so far. I am new to this so bare with me lol. So this will take the "n" items (which are all objectId's from "listID") and create promises for those n items? Im confused on how this will loop through each of the items separately. However I did try using this but received this: [Error]: function not found (Code: 141, Version: 1.7.5) – Will Von Ullrich Aug 14 '15 at 01:34
  • yes i created list as an NSArray. currently it has 4 test objectId values but it will need to be some number later on when this works – Will Von Ullrich Aug 14 '15 at 02:15
  • I am pulling the list array from my xcode project - not sure if that is clear or if it changes things – Will Von Ullrich Aug 14 '15 at 02:17
  • @WillVonUllrich you can try my second option then, one without `map`, also spraying `console.log` all over the place might give a clearer idea where the error is coming from – mido Aug 14 '15 at 02:25
  • alright. last question: the checkUserData function - does that work in conjunction with the Parse.Promise... after the for loop? – Will Von Ullrich Aug 14 '15 at 02:38
  • not after, it is part of for loop, a part of logic inside for loop is moved into the checkUserData – mido Aug 14 '15 at 02:42
  • sorry 1 more lol - where you say "// returns parse promise for a particular userdata" does anything need to be inserted into checkUserData() in place of userdata? same goes for promises in Parse.Parse.when() – Will Von Ullrich Aug 14 '15 at 03:16
  • I received this error when I ran the second code - Error Domain=Parse Code=141 "function not found" UserInfo=0x7f86b0ccdd40 {code=141, originalError=Error Domain=NSURLErrorDomain Code=-1011 "The operation couldn’t be completed. (NSURLErrorDomain error -1011.)", temporary=0, error=function not found, NSLocalizedDescription=function not found} – Will Von Ullrich Aug 14 '15 at 03:19
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/86951/discussion-between-mido22-and-will-von-ullrich). – mido Aug 14 '15 at 05:18