Cloud code skipping section of code - javascript

I never learnt javascript so please bear with me.
I have a cloud function that does all but the indicated section (>>):
Parse.Cloud.define("acceptRequest", function(request, response) {
var user = request.user;
var requestUser;
var requestObject;
var requestId = request.params.objectId;
var query = new Parse.Query(GameRequests);
query.get(requestId,{
//Get GameRequest Object - requestObject
success: function (object) {
var requestObject = object;
var sender = requestObject.get("from");
var senderId = sender[0];
var query = new Parse.Query(Parse.User);
query.get(senderId, {
//From GameRequest Object data, find sender of request "requestUser"
success: function (userObject) {
var requestUser = userObject;
var requestUserList = requestUser.get("SENTrequests")
var requestIndex = requestUserList.indexOf(requestId);
if (requestIndex > -1) {
requestUserList.splice(requestIndex, 1);
requestUser.set("SENTrequests",requestUserList);
if (requestUserList.length = 1) {
user.unset("SENTrequests");
}
}
var userList = user.get("RCDrequests");
var userIndex = userList.indexOf(requestId);
if (userIndex > -1) {
userList.splice(userIndex, 1);
user.set("RCDrequests",userList);
if (userList.length = 1) {
user.unset("RCDrequests");
}
}
requestObject.destroy({
success: function(requestObject) {
requestUser.add("partners",user.id);
user.add("partners",requestUser.id);
var firstmsg = new GameMessage();
var secondmsg = new GameMessage();
firstmsg.set("sender", user.id);
firstmsg.set("receiver", requestUser.id);
firstmsg.set("sent", 0);
firstmsg.set("received", 0);
firstmsg.set("receiverName", requestUser.getUsername());
secondmsg.set("sender", requestUser.id);
secondmsg.set("receiver", user.id);
secondmsg.set("sent", 0);
secondmsg.set("received", 0);
secondmsg.set("receiverName", user.getUsername());
Parse.Object.saveAll([requestUser, user, firstmsg, secondmsg], { useMasterKey: true },{
>> success: function() {
>> console.log("Saving messages again");
>> firstmsg.set("otherside", secondmsg.id);
>> secondmsg.set("otherside", firstmsg.id);
>>
>> Parse.Object.saveAll([firstmsg, secondmsg]);
},
error: function(error) {
}
});
response.success("Successful");
},
error: function(requestObject, error){
}
});
},
error: function (userObject,error) {
}
});
},
error: function (object,error) {
response.error("Error");
}
});
});
It is supposed to save the two messages' objectIds so each has a reference to the other.
What is causing this problem and how can I fix it?
Thank you

I think your sending your response.success("Successful") before the save has been completed. Move your response to the success handler of the save.
You should take a look at promises section. You will not need the deep nested functions you have currently.

Related

Parse.com JS looping through an array when using query.find()

I'm trying to query using each elements on the array as the constraint, but so far its has only given me one result.
Here is the array:
["C44","C43","C45","C117"]
Here what I have:
{var TestObject = Parse.Object.extend("TestObject");
var query = new Parse.Query(TestObject);
query.get("W7yuUsbbav", {
success: function(testObject) {
var subjectArray = testObject.get("subjects");
for (i = 0; i < subjectArray.length ; i++ ){
console.log(subjectArray[i]);
var query = new Parse.Query("Subjects");
query.equalTo("subCode", subjectArray[i]);
query.find({
success: function(results) {
$scope.$apply(function() {
$scope.subjects1 = results.map(function(obj) {
return {subCode: obj.get("subCode"), subName: obj.get("subName"), subDesc: obj.get("subDesc")};
});
});
},
error: function(error) {
}
});
}
},
error: function(object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and message.
}
});}
You can use the containedIn property of query.
var sampleId = "W7yuUsbbav";
var query1 = new Parse.Query("TestObject");
query1.get(sampleId).then(function (testObject) {
// Success
var subjectArray = testObject.get("subjects");
var query2 = new Parse.Query("Subjects");
query2.containedIn("subCode", subjectArray);
return query2.find();
}).then(function (subjectObjects) {
// Success
// results is an array of objects
}, function (error) {
// Error
});

Another Parse 'success/error not called' error

I recently posted an issue I had with another Parse CloudCode method, were the error was thrown that Error: success/error was not called. I am having that issue again but with a different method/scenario.
Parse.Cloud.define("background", function(request, response) {
var moments = require("cloud/moments.js");
var now = moments.moment();
var query = new Parse.Query("Group");
query.find({
success: function(results) {
for (var i = 0; i < results.length; i++) {
var object = results[i];
var events = object.get("Events");
var getUsers = false;
for (var q = 0; q < events.length; q++) {
var e = events[q];
if (e.get("date") == now) {
getUsers = true;
break;
}
}
if (getUsers == true) {
for (var q = 0; q < events.length; q++) {
var e = events[q];
if (e.get("date") == now) {
var relation = object.relation("created");
var partOne = e.get("name");
var outString1 = partOne.concat(" is now");
// generate a query based on that relation
var query = relation.query();
Parse.Push.send({
where: query, // Set our Installation query
data: {
alert: outString1
}
}, {
success: function() {
// Push was successful
},
error: function(error) {
// Handle error
}
});
var relation2 = object.relation("joined");
var partOnee = e.get("name");
var outString = partOnee.concat(" is now");
// generate a query based on that relation
var query2 = relation.query();
Parse.Push.send({
where: query2, // Set our Installation query
data: {
alert: outString
}
}, {
success: function() {
// Push was successful
},
error: function(error) {
// Handle error
}
});
e.destroy();
}
}
}
}
}
});
response.success();
});
Since this method involves more than just a simple query and return (as it has the for loop among other things) I am a bit confused on how to implement the Parse Promise stuff. If anyone could assist me in how I should go about implementing the promise stuff it would be much appreciated.
Parse documentation is very clear on how to use Promises and how to rewrite your pyramid code with .then() blocks instead.

Change URLs into files (Parse.com using Javascript CloudCode)

I need to batch change a number of image links (URL's links that exist within a class in) to image files (that Parse.com hosts).
Cloud code is (apparently) how to do it.
I've followed the documentation here but haven't had any success.
What I wanted to do is:
Take URL link from "COLUMN_1"
Make it a file
Upload file to "COLUMN_1" (overwrite existing URL). If this is dangerous- can upload it to a new column ("COLUMN_2").
Repeat for next row
This code did not work (this is my first time with JS):
imgFile.save().then(function () {
object.set("COLUMN_1", imgFile);
return object.save();
}).then(function (CLASSNAME) {
response.success("saved object");
}, function (error) {
response.error("failed to save object");
});
Can anyone recommend how to do this?
OK- this successfully works for anyone else trying.
Parse.Cloud.job("convertFiles", function(request, status) { //Cuts the rundata out of poor runs
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
// Tell the JS cloud code to keep a log of where it's upto. Manually create one row (in class "debugclass") to get an object Id
Parse.Cloud.useMasterKey();
var Debug = Parse.Object.extend("debugclass");
var queryForDebugObj = new Parse.Query(Debug);
queryForDebugObj.equalTo("objectId", "KbwwDV2S57");
// Query for all users
// var queryForSublist = new Parse.Query(Parse.Object.extend("gentest"));
queryForDebugObj.find({
success: function(results) {
var debugObj = results[0];
var processCallback = function(res) {
var entry = res[0];
var debugObj = results[0];
debugObj.set("LastObject", entry.id);
debugObj.save();
Parse.Cloud.httpRequest({
url: entry.get("smallImage2"),
method: "GET",
success: function(httpImgFile)
{
console.log("httpImgFile: " + String(httpImgFile.buffer));
var imgFile = new Parse.File("picture.jpg", {base64: httpImgFile.buffer.toString('base64')});
imgFile.save().then(function () {
console.log("2");
entry.set("smallImage1", imgFile);
entry.save(null, {
success: function(unused) {
debugObj.increment("itemDone");
sleep(20);
res.shift();
if (res.length === 0) {
process(entry.id);
return;
}
else {
processCallback(res);
}
},
error: function(unused, error) {
response.error("failed to save entry");
}
});
});
},
error: function(httpResponse)
{
console.log("unsuccessful http request");
response.error(responseString);
}
});
};
var process = function(skip) {{
var queryForSublist = new Parse.Query("genpants");
if (skip) {
queryForSublist.greaterThan("objectId", skip);
console.error("last object retrieved:" + skip);
}
queryForSublist.ascending("objectId");
queryForSublist.find().then(function querySuccess(res) {
processCallback(res);
}, function queryFailed(reason) {
status.error("query unsuccessful, length of result " + result.length + ", error:" + error.code + " " + error.message);
});
}};
process(debugObj.get("LastObject"));
},
error: function(error) {
status.error("xxx Uh oh, something went wrong 2:" + error + " " + error.message);
}
});
});

Getting JSON from a Function in javascript

So this will be a lot of code, but what matter is on line 22-25, and line 87-91. The rest of the code works. I have a nested function and want to return the JSON string. Using console.log I can tell it is running properly but will not return the JSON string. Look for the part that says //---------this part-------. There are two parts that I am asking about.
exports.post = function(request, response) {
var mssql = request.service.mssql;
//var data = '{"userID":"ryan3030#vt.edu1"}';
var inputJSON = request.body.JSONtext;
var json = JSON.parse(inputJSON);
var userID = json.userID;
mssql.query("EXEC getMeetingInfo ?", [userID],
{
success: function(results3) {
var meetingsToday = results3.length;
var meetingID = results3[0].meetingID;
var meetingName = results3[0].meetingName;
var meetingDescription = results3[0].meetingDescription;
var meetingLength = results3[0].meetingLength;
var meetingNotes = results3[0].meetingNotes;
var hostUserID = results3[0].hostUserID;
//--------------------------------------THIS PART------------------------------
var JSONfinal = allInfoFunction(mssql, meetingID, userID, meetingName, meetingDescription, meetingLength, meetingNotes, hostUserID, meetingsToday);
console.log(JSONfinal);//DOES NOT WORk
response.send(statusCodes.OK, JSONfinal);//DOES NOT WORK
//---------------------------------BETWEEN THESE----------------------------------
},
error: function(err) {
console.log("error is: " + err);
response.send(statusCodes.OK, { message : err });
}
});
};
function allInfoFunction(mssql, meetingID, userID, meetingName, meetingDescription, meetingLength, meetingNotes, hostUserID, meetingsToday){
mssql.query("EXEC getLocation ?", [meetingID],
{ success: function(results2) {
var meetingLocation = results2[0].meetingLocation;
var JSONlocation = {"meetingLocation": meetingLocation};
mssql.query("EXEC getDateTime ?", [meetingID],
{ success: function(results1) {
var length = results1.length;
var dateTime = [];
dateTime[0] = results1[0].meetingDateTime;
for (var x= 1; x < length; x++) {
dateTime[x] = results1[x].meetingDateTime;
}
//console.log(dateTime);
mssql.query("EXEC getDateTimeVote",
{ success: function(results) {
//console.log(results);
var JSONoutput2 = {};
var JSONtemp = [];
var length2 = results.length;
for(var j = 0; j < length; j++){
var vote = false;
var counter = 0;
for(var z = 0; z < length2; z++){
var a = new Date(results[z].meetingDateTime);
var b = new Date(results1[j].meetingDateTime);
if(a.getTime() === b.getTime()){
counter = counter + 1;
}
if((a.getTime() === b.getTime()) && (results[z].userID == userID)){
vote = true;
}
}
var meetingTimeInput = {"time": b, "numVotes": counter, "vote": vote}
JSONtemp.push(meetingTimeInput);
JSONoutput2.meetingTime = JSONtemp;
}
var JSONfinal = {};
var mainInfoArray = [];
var JSONmainInfo = {meetingID: meetingID, meetingName: meetingName, meetingDescription: meetingDescription, meetingLength: meetingLength, meetingNotes: meetingNotes, hostUserID: hostUserID, meetingLocation: meetingLocation };
JSONmainInfo.meetingTime = JSONtemp;
JSONfinal.numMeetingsToday = meetingsToday;
mainInfoArray.push(JSONmainInfo);
JSONfinal.meetingList = mainInfoArray;
//response.send(statusCodes.OK, JSONfinal);
//---------------------------------------AND THIS PART-------------------------------
console.log(JSON.stringify(JSONfinal));//This outputs the correct thing
var lastOne = JSON.stringify(JSONfinal);
return lastOne; //ths dosent work
//-------------------------------------BETWEEN THESE-----------------------------------
},
error: function(err) {
console.log("error is: " + err);
//response.send(statusCodes.OK, { message : err });
}
});
},
error: function(err) {
console.log("error is: " + err);
//response.send(statusCodes.OK, { message : err });
}
});
},
error: function(err) {
console.log("error is: " + err);
//response.send(statusCodes.OK, { message : err });
}
});
}
I've done a little refactoring to your code to take a more modular approach. It becomes quite tricky to debug something like what you have above. Here it is:
exports.post = function(request, response) {
var mssql = request.service.mssql;
var inputJSON = request.body.JSONtext;
var json = JSON.parse(inputJSON);
var userID = json.userID;
var JSONFinal = {};
getMeetingInfo(userID);
function getMeetingInfo(userID){
mssql.query("EXEC getMeetingInfo ?", [userID], {
success: function(results){
JSONFinal.meetingsToday = results.length;
JSONFinal.meetingID = results[0].meetingID;
JSONFinal.meetingName = results[0].meetingName;
JSONFinal.meetingDescription = results[0].meetingDescription;
JSONFinal.meetingLength = results[0].meetingLength;
JSONFinal.meetingNotes = results[0].meetingNotes;
JSONFinal.hostUserID = results[0].hostUserID;
// Call next function
getLocation(JSONFinal);
},
error: function(err) {
console.log("error is: " + err);
response.send(statusCodes.OK, { message : err });
}
});
}
function getLocation(){
mssql.query("EXEC getLocation ?", [JSONFinal.meetingID], {
success: function(results) {
JSONFinal.meetingLocation = results[0].meetingLocation;
// Call next function
getDateTime(JSONFinal);
},
error: function(err) {
console.log("error is: " + err);
}
});
}
function getDateTime(){
mssql.query("EXEC getDateTime ?", [JSONFinal.meetingID], {
success: function(results) {
var length = results.length;
var dateTime = [];
for (var x= 0; x < length; x++) {
dateTime[x] = results[x].meetingDateTime;
}
// Call next function
getDateTimeVote(dateTime);
},
error: function(err){
console.log("error is: " + err);
}
});
}
function getDateTimeVote(dateTime){
mssql.query("EXEC getDateTimeVote", {
success: function(results) {
var JSONtemp = [];
var length2 = results.length;
for(var j = 0; j < dateTime.length; j++){
var vote = false;
var counter = 0;
for(var z = 0; z < length2; z++){
var a = new Date(results[z].meetingDateTime);
var b = new Date(results1[j].meetingDateTime);
if(a.getTime() === b.getTime()){
counter = counter + 1;
}
if((a.getTime() === b.getTime()) && (results[z].userID == userID)){
vote = true;
}
}
var meetingTimeInput = {"time": b, "numVotes": counter, "vote": vote}
JSONtemp.push(meetingTimeInput);
}
var JSONmainInfo = {
meetingID: JSONFinal.meetingID,
meetingName: JSONFinal.meetingName,
meetingDescription: JSONFinal.meetingDescription,
meetingLength: JSONFinal.meetingLength,
meetingNotes: JSONFinal.meetingNotes,
hostUserID: JSONFinal.hostUserID,
meetingLocation: JSONFinal.meetingLocation
meetingTime: JSONtemp
};
var JSONfinal = {
numMeetingsToday: JSONFinal.meetingsToday,
meetingsList: [JSONmainInfo]
};
// Call next function
sendResponse(JSON.stringify(JSONfinal));
},
error: function(err) {
console.log("error is: " + err);
}
});
}
function sendResponse(data){
response.send(statusCodes.OK, data);
}
};
It looks a lot different but the functionality is pretty much the same. The key point if you look at the code is that each subsequent function is executed only after the success of the previous function. This effectively chains the methods together so that they are always executed in order and is the key point of difference.
One thing to note here is the similarity between your
allInfoFunction(...
and my
getMeetingInfo(userID)
Both of these will return undefined more or less immediately, after the MSSQL query is sent to the server. This is because the request is fired asynchronously, and the javascript continues to run through the code. After it's fired of the asynchronous request, it has nothing left to do in that function, so it returns. There is no return value specified so it returns nothing (or undefined if you will).
So all in all, the code in the question code will return undefined and then attempt to send a response before anything has actually happened. This code fixes that problem by firing the sendResponse after all the queries have been executed.
I refactored this code in a text editor and haven't run it, or checked it for errors, so follow the basic outline all you like but it may not be a good idea to copy and paste it without checking it's not broken

WinRT - StreamSocket - Connection closing while reading data via LoadAsync

I'm trying to send HTTP requests via StreamSocket, but response is truncated with
"failedWinRTError: The object has been closed."
Here is my code:
var count, hostName, raw_request, raw_response, reader, socketProtection, startReader, streamSocket, writer;
streamSocket = new Windows.Networking.Sockets.StreamSocket();
hostName = new Windows.Networking.HostName("www.reddit.com", "80");
raw_response = "";
count = 0;
startReader = function() {
return reader.loadAsync(8 * 1000).done(function(bytesRead) {
raw_response += reader.readString(reader.unconsumedBufferLength);
if (raw_response.indexOf("</html>") > 0) {
return;
} else {
startReader();
}
}, function(error) {
raw_response += reader.readString(reader.unconsumedBufferLength);
window.raw_response = raw_response;
return;
});
};
streamSocket.connectAsync(hostName, "80", 0).done(function(response) {
var string;
reader = new Windows.Storage.Streams.DataReader(streamSocket.inputStream);
reader.inputStreamOptions = 1;
writer = new Windows.Storage.Streams.DataWriter(streamSocket.outputStream);
string = "Hello world";
writer.writeString(raw_request);
return writer.storeAsync().done(function() {
writer.flushAsync();
writer.detachStream();
return startReader();
});
});
I noticed that the beginning of the response is truncated as well.
This is what I get at the beginning of HTTP responses.
/1.1 200 OK
Also strangely... HTTPS requests work perfectly.
Any idea what I'm doing wrong? Thanks :)
Remove http:// from the host name and the second parameter is not needed:
var hostName = new Windows.Networking.HostName("www.reddit.com");
Use this object in ConnectAsync, just hostname and service name parameters are needed:
streamSocket.connectAsync(hostName, "80").done(function (response) {
// ....
}, function (error) {
console.log(error);
});
UPDATE: Ok, if the connection is being closed, probably the server closes it. Are you sending a well formed request? Here is an example:
var raw_request, raw_response, reader, writer;
var streamSocket = new Windows.Networking.Sockets.StreamSocket();
function doRequest() {
var hostName = new Windows.Networking.HostName("www.reddit.com");
streamSocket.connectAsync(hostName, "808").then(function () {
reader = new Windows.Storage.Streams.DataReader(streamSocket.inputStream);
reader.inputStreamOptions = Windows.Storage.Streams.InputStreamOptions.partial;
writer = new Windows.Storage.Streams.DataWriter(streamSocket.outputStream);
raw_request = "GET / HTTP/1.1\r\nHost: www.reddit.com/\r\nConnection: close\r\n\r\n";
writer.writeString(raw_request);
return writer.storeAsync();
}).then(function () {
raw_response = "";
return startReader();
}, function (error) {
console.log(error);
});
}
function startReader() {
return reader.loadAsync(99999999).then(function (bytesRead) {
raw_response += reader.readString(reader.unconsumedBufferLength);
if (bytesRead === 0) {
window.raw_response.value = raw_response;
return;
}
return startReader();
});
};

Categories

Resources