Parse server cloud code getting and updating an object - javascript

When a user shares a post I want to be able to give them a reward point for doing so. I am calling the cloud function from xcode like this.
PFCloud.callFunction(inBackground: "shares", withParameters: ["objectID" : "z2pU3UDFrh"])
I hardcoded an object id for now just to check if its working.
Here is my cloud code function that gets called
Parse.Cloud.define("shares", function(request, response) {
var shareQuery = new Parse.Query("Parse.POSTS");
shareQuery.get(request.params.objectID, {
success: function(object) {
console.log(object)
object.increment("score");
object.save();
},
error: function(error) { },
useMasterKey: true
});
});
when I check the logs it prints "undefined" and the score remains unchanged

Replace var shareQuery = new Parse.Query("Parse.POSTS");
with var shareQuery = new Parse.Query("POSTS");
Parse.Cloud.define("shares", function(request, response) {
var shareQuery = new Parse.Query("POSTS");
shareQuery.get(request.params.objectID, {
success: function(object) {
console.log(object)
object.increment("score");
object.save();
},
error: function(error) {
console.error(error)
},
useMasterKey: true
});
});

Related

how to use Meteor.http.call

I am trying to send sms using Meteor.http.call.I take two errors:
First error:When page loaded,"WebSocket connection to
'ws://localhost:3000/sockjs/632/i0uapg48/websocket' failed: WebSocket
is closed before the connection is established."
Second error:when I click ebultenkydet,"Uncaught TypeError: Cannot
read property 'call' of undefined"
Template.footerLayout.events({
'click #ebultenkaydet': function(e, template) {
var auth_url="http://api.sorentesms.com/index.php"
var result = Meteor.http.call("POST", auth_url, {
data: {
'apiNo':'1',
'user':'test',
'pass':'test123',
'message':'hi',
'number':'+905075587***',
'from':'test',
},
headers: {
"content-type":"application/json",
"Accept":"application/json"
},
})
}
});
Can you help me about it?
Thank you all
You are sending your http request inside a client side block, and Meteor.http is only available on sever side. You have to put this block in a Meteor.isServer block.
Don't forget to meteor add http to able to use the code:
Let me rewrite your code:
if (Meteor.isServer) {
Meteor.methods({
authCall: function () {
this.unblock(); // Make sure server doesn't get block from this call
var auth_url="http://api.sorentesms.com/index.php";
return Meteor.http.call("POST", auth_url, {
data: {
'apiNo':'1',
'user':'test',
'pass':'test123',
'message':'hi',
'number':'+905075587***',
'from':'test',
},
headers: {
"content-type":"application/json",
"Accept":"application/json"
},
})
}
});
}
Template.footerLayout.events({
'click #ebultenkaydet': function(e, template) {
Meteor.call("authCall", function(error, results) {
console.log(results); //results.data should be a JSON object
});
});

success/error on Parse.Promise

I have written a series of Parse Promises and am now getting error 141 when I make a request to this cloud code function. I have tried placing success: / error: all over the function where I think they belong based on the Parse DOCS.
Request
{
"projectDescription": "Testing saveProject",
"projectTitle": "This is only a test, in the event of a real post this will have an actual description",
"isEmailEnabled": true,
"shareEmails": [
"max#gmail.com",
"nat#gmail.com",
"noob#gmail.com"
],
"userId": "sLmOf4fZFL"
}
Parse.Cloud.define("saveProject", function(request, response) {
var emails = request.params.shareEmails;
var user = request.params.userId;
var projectDescription = request.params.projectDescription;
var projectTitle = request.params.projectTitle;
var emailStatus = request.params.isEmailEnabled;
var ProjectClass = Parse.Object.extend("Project");
var EmailsClass = Parse.Object.extend("Email");
var EmailsClassAssignment = Parse.Object.extend("EmailAssignment");
var project = new ProjectClass();
var projectO;
project.set("title", projectTitle);
project.set("createdBy", {
"__type": "Pointer",
"className": "_User",
"objectId": user
});
project.set("description", projectDescription);
project.set("status", true);
project.set("emailShareEnabled", emailStatus);
project.save().then(function(results) {
projectO = results;
console.log(projectO);
return Parse.Promise.when(emails.map(function(emailAddress) {
var email = new EmailsClass();
email.set("address", emailAddress);
return email.save();
}));
}).then(function() {
return Parse.Promise.when(emails.map(function(emailQuery) {
var queryEmail = new Parse.Query("Email");
queryEmail.equalTo("address", emailQuery);
return queryEmail.find().then(function(results) {
var emailJSON = results[0].toJSON();
var emailObjectId = emailJSON.objectId;
var projectJSON = projectO.toJSON();
var projectId = projectJSON.objectId;
var assignment = new EmailsClassAssignment();
assignment.set("createdBy", {
"__type": "Pointer",
"className": "_User",
"objectId": user
});
assignment.set("email", {
"__type": "Pointer",
"className": "Email",
"objectId": emailObjectId
});
assignment.set("project", {
"__type": "Pointer",
"className": "Project",
"objectId": projectId
});
assignment.save(null, {
success: function() {
console.log("Successfully saved project");
},
error: function(error) {
console.log("There was an error saving" + error.message);
}
});
});
}));
}).then( function() {
response.success();
});
});
The basic ideas look okay, but the code is kind of a jumble of callback parameters and promises. I took the liberty of refactoring into simpler, promise-returning logical chunks so we could see what's going on.
You highlighted the .map functions in the post. Not sure what the issue was there, so the code I suggest uses underscorejs, which can be easily included in the cloud as follows:
var _ = require('underscore');
First, return a promise to save a "project" given most of the params to your cloud function:
function createProject(params) {
var ProjectClass = Parse.Object.extend("Project");
var project = new ProjectClass();
var emails = request.params.shareEmails;
var user = request.params.userId;
var projectDescription = request.params.projectDescription;
var projectTitle = request.params.projectTitle;
var emailStatus = request.params.isEmailEnabled;
project.set("title", projectTitle);
project.set("createdBy", {
"__type": "Pointer",
"className": "_User",
"objectId": user
});
project.set("description", projectDescription);
project.set("status", true);
project.set("emailShareEnabled", emailStatus);
return project.save();
}
Next, create "Email"'s (which are objects) given an array of email address strings. (You would do well to more carefully distinguish the objects and the strings in your naming, but I tried to hew to original nomenclature in the code)
function createEmails(emails) {
var EmailsClass = Parse.Object.extend("Email");
var toSave = _.map(emails, function(emailAddress) {
var email = new EmailsClass();
email.set("address", emailAddress);
return email;
});
// like the when() function, but (possibly) fewer requests
return Parse.Object.saveAll(toSave);
}
This is where the original code took a turn for the worse. In it, the code just finished creating the Email objects, then for some reason, it attempts to query those objects. But we have them in hand already, on the fulfullment of the promises to save.
The method below, takes already built email objects (named pedantically, to emphasize that they are objects) and other ingredients to an "EmailClassAssignment". Notice how we can assign pointers directly with objects when we have a PFObject in hand:
function createEmailClassAssignments(emailObjects, project, userId) {
var EmailsClassAssignment = Parse.Object.extend("EmailAssignment");
var toSave = _.map(emailObjects, function(emailObject) {
var assignment = new EmailsClassAssignment();
// the real objects can be used as parameters to set for pointer columns
assignment.set("email", emailObject);
assignment.set("project", project);
// we only have the userId, not a user object, so we can either query
// for the user or take the shortcut that you've been taking
project.set("createdBy", {
"__type": "Pointer",
"className": "_User",
"objectId": user
});
return assignment;
});
return Parse.Object.saveAll(toSave);
}
With all that done, the cloud function becomes more legible:
Parse.Cloud.define("saveProject", function(request, response) {
var project;
createProject(params).then(function(result) {
project = result;
return createEmails(request.params.shareEmails);
}).then(function(emailObjects) {
return createEmailClassAssignments(emailObjects, project, request.params.userId);
}).then(function() {
console.log("Successfully saved project");
// I took the liberty of returning the new project to the caller
response.success(project);
}, function(error) {
console.log("There was an error saving" + error.message);
resoonse.error(error);
});
});
CAUTION: obviously, there's no way for me to test any of the foregoing. I strongly urge you to test the functions yourself, preferably individually before expecting the combination to work. Hopefully, the refactor demonstrates a cleaner way to use promises and a reasonable decomposition of parts to test and use individually.
From the looks of your code, you simply need to add a return in front of assignment.save() as you aren't waiting for that to finish otherwise.
Lastly you should add an error catcher at the very end:
.then(null, function(error) {
console.log(error);
response.error(error);
});

Not able to update parent for all PortfolioItem/Feature which I copied for particular PortfolioItem/MMF

I am trying to set parent for features which I copied for particular MMF, but parent is getting set for only last feature.
Below line of code to set the parent
Record is new feature object
_newParent is the MMF object, where I am doing wrong
record.set("Parent", _newParent.get("_ref")),
Need help please.Any suggestions?
Whole is method is this
_genericInnerCopy: function(_childObj) {
that = this;
model = that.model;
var record = Ext.create(model, {
Name: _childObj.get('Name'),
//Parent: _newParent.get("_ref");,
});
record.save({
callback: function(result, operation) {
if(operation.wasSuccessful()) {
console.log("Done");
//that._copyChild();
} else {
console.log("error");
}
}
})
that._all_pis.push(record);
console.log("all pis values", that._all_pis);
var store = Ext.create('Rally.data.custom.Store', {
data: that._all_pis,
listeners: {
load: that._updateAll,
scope: that
},
});
//console.log("record values", that._all_pis);
},
_updateAll: function(store,data) {
console.log("store values", store);
console.log("data values", data);
Rally.data.BulkRecordUpdater.updateRecords({
records: data,
propertiesToUpdate: {
Parent: _newParent.get("_ref")
},
success: function(readOnlyRecords){
//all updates finished, except for given read only records
},
scope: that
});
//that._createNewItems(that._all_pis);
},
The problem in your original question was that your code wasnt spitting out the errors in the callback. To see the errors you can console.log(operation.getError()) or console.log(operation) and inspect the output.

Adding data to Users and then saving them using Parse Cloud Code

I'm trying to make a cloud function which saves the sender's objectId and username as an array, inside the array "request", for the target and have the target's objectId and username saved as an array, in the array "pending" for the sender.
Parse.Cloud.define("newGameRequest", function(request, response) {//A
// Get the user who called the function
var user = request.user;
var target;
var query = new Parse.Query(Parse.User);
query.get(request.params.friendId, {
success: function(object) {
var target = object;
var friendInfo = [target.objectId, target.username];
var userInfo = [user.objectId, user.username];
user.add("pending",friendInfo);
target.add("request",userInfo);
Parse.Object.saveAll([user, target], { useMasterKey: true });
response.success("Success");
},
error: function(object, error) {
response.error(error);
}
});
});
Looking in the data browser shows that the arrays for each respective user were saved, but saved with null values only ([[null,null]] for both).
The call is from an iOS device and is the following:
[PFCloud callFunctionInBackground:#"newGameRequest"
withParameters:#{#"friendId": self.friend.objectId}
block:^(NSString *result, NSError *error) {
if (!error) {
}
else {
NSLog(#"%#",result);
}
}];
self.friend.objectId has been tested and is the right result.
What is the issue with my cloud code?
I'm an idiot.
getting the object Id of user is the like the following:
user.id
and getting the username is done like this:
user.getUsername()

Error in resource configuration. Expected response to contain an object but got an array

I have an angular response that expects an array and the service call passes an array(can see it in network tab of chrome dev tools).
but I'm getting the following error in chrome console.
Error in resource configuration. Expected response to contain an object but got an array
here is my angular service:-
physicalServerModule.factory("physicalServerServices", ['$resource',
function ($resource) {
var host = app.general.host;
var port = app.general.port;
var serverItemPath = 'v1/physicalserver/:x';
var serverPath = 'v1/physicalserver/list';
return {
physicalServer: function () {
return $resource(host + serverPath,{}, {
query: {
method: 'GET',
isArray: true
},
create: {
method: 'POST'
}
});
}
};
}]);
and I'm calling my service as below:-
var tileServiceCall = physicalServerServices.physicalServer();
tileServiceCall.get({},{}).$promise.then(function (response) {
app.meta.physicalserver.tileItems = JSON.stringify(response);
}, function (error) {
alert("error");
});
my angularjs version is 1.2.15
can someone point me the root cause?
Change tileServiceCall.get(..) to tileServiceCall.query(...).

Categories