Jorge
Jorge

Reputation: 1532

JavaScript and Cloud code function, share the same var

I use parse.comas backend service for my iOSapp. I was trying to do everything in objective-c since I don't have any experience with JavaScript, but turns out I will need to develop some Cloud Code Functions in JavaScript to complete my app.

A simple routine I'm trying to create:

  1. User retrieves an object using a Cloud Function.
  2. User saves another object in a different class.
  3. An afterSavefunction runs in the cloud to update object first retrieved.

Now, here is my code:

var UserConfigOrientador = Parse.Object.extend("UserConfigOrientador");
var query = new Parse.Query(UserConfigOrientador);

Parse.Cloud.define('pegarOrientadorLivre', function(request, response) {
    Parse.Cloud.useMasterKey();
    query.greaterThan("entrevistasDisponibilidade", 0);
    query.first({
       success: function(results) {
            response.success(results);
            query = results;
        },
        error: function(error) {
            response.error('Favor, checar rede e tentar novamente.');
        }
    });
});

// AfterSave
Parse.Cloud.afterSave("Agenda", function(request) {
    Parse.Cloud.useMasterKey();
    query.set("entrevistasDisponibilidade", 70);
    query.save();
        }
    });
});

Now, the second function is not working, I'm getting the message that Object has no set method.

Basically, my questions are:

How can I share data between functions? Should I keep everything in main.js or can I use another file?

I'm using webStorm for development. And the question about main.js is that after a while I will have a lot of functions and I am trying to figure out how to organize my code.

Upvotes: 1

Views: 711

Answers (2)

Timothy Walters
Timothy Walters

Reputation: 16884

Your issue is one of scope, and poorly named variables that you're reusing for multiple purposes.

You define your query variable as a query, use it, but inside the success handler you set it to the result of the query (you now have a variable called query which is actually an instance of your UserConfigOrientador class).

When that Cloud Code finishes running, the result goes out of scope and is most likely set to undefined. You shouldn't be trying to share variables between multiple Cloud Code methods like that.

Is there something on the Agenda object that can let you know which UserConfigOrientador to update? Perhaps you could add a pointer property to the UserConfigOrientador? If you did, then you could use the following:

// AfterSave
Parse.Cloud.afterSave("Agenda", function(request) {
    Parse.Cloud.useMasterKey();
    var userConfigOrientadorQuery = new Parse.Query("UserConfigOrientador");
    // read "userConfigOrientador" pointer property on "Agenda" object
    var userConfigId = request.object.get("userConfigOrientador").id;
    userConfigOrientadorQuery.get(userConfigId, {
        success: function(userConfigOrientador) {
            userConfigOrientador.set("entrevistasDisponibilidade", 70);
            userConfigOrientador.save();
        }
    });
});

Upvotes: 1

jmk2142
jmk2142

Reputation: 8581

Mm.. I don't think it quite works the way you expect.

When your Cloud code runs, your initial var query declaration is indeed available within the scope of your cloud function and afterSave function. However, you're not passing it in correctly. As a matter of fact, I'm a little confused because your query seems to be requesting a UserConfigOrientador object while your afterSave is on an Agenda object.

So there are two different things going on here. Since you don't actually save an agenda object, I'm assuming that your response.success() returns a JSON of the UserConfigOrientador object back to client side at which point you do some manipulation then save the Agenda object based on that result.

At this point, when you save() the Agenda object now the afterSave() function will run but your query value will be the var query = new Parse.Query(UserConfigOrientador); which does not have a set method. This is why you get the error.

I'm not even sure your query = results; line will actually execute as you should be calling it at the END of your sub-routine and it signals to Parse that it is the end.

If you can tell me how you're saving the Agenda object I can probably complete the picture.

EDIT: --- abstracted but maybe this is the pattern you're looking for...

var ObjectA = Parse.Object.extend('ObjectA');
var queryObjectA = new Parse.Query('ObjectA');

Parse.Cloud.define('findObjectX', function(request, response) {
Parse.Cloud.useMasterKey();
// other query options here...
query.first({
   // the first() function will return a Parse.Object
   success: function(objectX) {
       // Now you have objectX
       // Now you want to save some other object
       var otherObj = new ObjectA();
       // Do things to otherObj
       otherObj.save({
           success: function(result) { // will be the saved otherObj
               // Now you do stuff to your queried obj and save
               objectX.set('something', result); // or whatever
               // Note, it accomplishes what I think you want without afterSave()
           }
       }); // async... but we can just let this guy go

   },
   error: function(error) {
       response.error('Favor, checar rede e tentar novamente.');
   }
});
});

Upvotes: 0

Related Questions