Reputation: 3751
This is a parse.com question partly and their API is unique. However, the problem I am having is a little bit because I am new to javascript and dont fully undrestand it.
My code is very well commented on what I am suppose to do! There is a section of code that is commented in all caps, that is the section I am having trouble with.
Any insight to how to control javascripts async calls in my code will be useful.
CODE
Parse.Cloud.define("StartSession", function(request, response) {
var query =new Parse.Query("User"); // search the User class
query.containedIn("username", request.params.myArray); //get the users that are in my array
query.find({
success: function(results) { // if found do this
// Didn't find a keyword to match tags so create new keyword
//result is all the users that are in this session to be created.
var Session = Parse.Object.extend("Session"); // create a session objsect
var mySession = new Session(); // create an instance of the session
console.log("the log is");
var users = []; // all the users
var deviceID = []; // their corsponding ids
users.push(request.params.user); // add an extra item to the users array that is being passed into this funciton on the original call
for (var i = 0; i <= results.length - 1; i++) { // iterate all of the results returned from the find
users.push(results[i].get("username")); // get their username attribute and add it to the users array
deviceID.push(results[i].get("installID")); // get their associated installID and add it to deviceID
};
// users.splice(users.indexOf(request.params.user), 1);
mySession.set("users", users); // put all of the supplied users found into this session
mySession.set("owner", request.params.user) // set the owner of the session. This was passed in
console.log(results);
var installs = new Parse.Query(Parse.Installation); // get the installs class
mySession.save(null, { // save the session
success: function(gameScore) { //if successful go on
// Execute any logic that should take place after the object is saved.
console.log("getting"); // logging
for (var i = deviceID.length - 1; i >= 0; i--) { //iterate all of the deviceIDs from the above
var sessionID = mySession.id; // get the session id for the session that was just created
installs.contains("objectid", deviceID[i]); // make a search for the installs class
installs.find({ // find given the above search
success: function(myResults){ // if success
console.log("getting2"); // log something
var tempChannels = myResults.get('channels'); // get the given users channels list and save it into an array
console.log(myResults); // log something
tempChannels.push(sessionID); // add the new sessionId to their list of channels
myResults.set("channels", tempChannels); // put back the newly modified array which should be a list of channels
}, // THE SUCCESS CODE ABOVE IS NOT WORKING OR DOING ANYTHING. CHANNEL IS NOT CHANGING NOR IS ANYTHING GETTING LOGGED
error: function(error){ // NOR IS THE ERROR CODE
console.log("getting 3")
console.log("asD");
}
});
// var channels = deviceID[i].get("channels");
// console.log("adding a channel for "+deviceID[i]);
// channels.push(sessionID);
// deviceID[i].set("channels", channels);
}; //THE REST IS UNIMPORTANT FOR THIS QUESTI
var targets = new Parse.Query(Parse.Installation);
console.log("check point 1 "+sessionID);
//targets.equalTo('deviceType', ['android']);
targets.contains("channels", sessionID)
if (targets.length > 0) {console.log("There are more than one recipiants for this")};
console.log("check point 2");
console.log(targets.length);
Parse.Push.send({
where: targets,
data: {
alert: "test",
}
}, {
success: function() {
// Do something on success
console.log("Was able to send notifications");
console.log("check point 3");
},
error: function() {
// Do something on error
console.log("Error sending the notifications");
console.log("check point 4");
}
});
response.success(users);
},
error: function(gameScore, error) {
// Execute any logic that should take place if the save fails.
// error is a Parse.Error with an error code and description.
response.success("ERROR");
console.log("check point 5");
}
});
},
error: function() {
response.error("Found nothing");
console.log("check point 6");
}
});
});
I found a few posts regarding the same sort of this here but I did not make the mistake of having one installs query. I make one for each iteration in the loop
The main problem is that:
for (var i = deviceID.length - 1; i >= 0; i--) { //iterate all of the deviceIDs from the above
var sessionID = mySession.id; // get the session id for the session that was just created
installs.contains("objectid", deviceID[i]); // make a search for the installs class
installs.find({ // find given the above search
success: function(myResults){ // if success
console.log("getting2"); // log something
var tempChannels = myResults.get('channels'); // get the given users channels list and save it into an array
console.log(myResults); // log something
tempChannels.push(sessionID); // add the new sessionId to their list of channels
myResults.set("channels", tempChannels); // put back the newly modified array which should be a list of channels
}, // THE SUCCESS CODE ABOVE IS NOT WORKING OR DOING ANYTHING. CHANNEL IS NOT CHANGING NOR IS ANYTHING GETTING LOGGED
error: function(error){ // NOR IS THE ERROR CODE
console.log("getting 3")
console.log("asD");
}
which is not executing. No error logs no success logs just doesnt get called.
I feel like it has to do with the async nature. The process terminates and the calls never get called back.
Upvotes: 1
Views: 484
Reputation: 5215
I think you're right that the source of the issue appears to be due to the callbacks. In the for loop you highlighted, you're not waiting for those find() calls to complete before continuing. The same is true for the Push after that. I've greatly simplified your code to illustrate what's happening. In short, response.success() is called before the asyncs finish so you never see the callbacks.
Parse.Cloud.define("StartSession", function(request, response) {
query.find({
success: function(results) {
mySession.save(null, {
success: function(gameScore) {
for (var i = deviceID.length - 1; i >= 0; i--) {
installs.find(); // not waiting for this
};
Parse.Push.send(); // not waiting for this
// called before the async's fire so no callbacks happen
response.success(users);
},
error: function(gameScore, error) {}
});
},
error: function() {}
});
});
I'd suggest using Promises to simplify things a bit. That would look something like this:
Parse.Cloud.define("StartSession", function(request, response) {
query.find().then(function(results) {
return mySession.save();
}).then(function(mySession) {
var installQueries = [];
for (var i = deviceID.length - 1; i >= 0; i--) {
installQueries.push(installs.find()); // not waiting for this
};
// wait for all the install queries to finish
return Parse.Promise.when(installQueries);
}).then(function() {
return Parse.Push.send();
}).then(response.success, response.error);
});
Upvotes: 5