I am calling this function from my android app,
Parse.Cloud.define('addFriendRequest', function(request, response) {
var userObjectId = request.params.userObjectId;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userObjectId });
var relation = Parse.Relation(user, 'friendRequests');
relation.add(request.user);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success("Successfully added friend Request");
}, function(error) {
response.error("An error has occurred")
});
});
And an errror is being thrown of type
TypeError: Cannot call method 'add' of undefined at main.js:10:11
I am relatively new to javascript so any advice would be great. Also the relation friendRequests exists already.
This should work.
Parse.Cloud.define('addFriendRequest', function(request, response) {
Parse.Cloud.useMasterKey();
var userObjectId = request.params.userObjectId;
var user = Parse.User.createWithoutData(userObjectId);
var relation = user.relation('friendRelation');
relation.add(request.user);
user.save().then(function(user) {
response.success("Successfully added friend Request");
}, function(error) {
response.error("An error has occurred")
});
});
Some clarification of what is going on here and why your code did not work.
First of all, it is a good practice to put Parse.Cloud.useMasterKey(); right in the beginning of the function.
I see that you have the objectId of user in the beginning and that you would like to use the user based on its objectId. I order to do that, you should use Parse.User.createWithoutData('yourObjectIdHere') method. What you are actually doing for this step, is that you are creating a new user, rather then creating a reference for the one you already have in the database.
If you want to get a relation of a particular object (User object in your case) your use Parse.Object.relation('putRelationKeyHere'). You are actually creating a new relation instead of accessing the existing one.
I would recommend you to read Parse Javascript Guide in order to learn the recommended techniques.
Related
To summarize, I have a mongodb database with a 'groupcollection' in it. One of the attributes is called 'deleted' and it has values either true or false. I want to update the value of 'deleted' for a specific document using 'groupname' as the query attribute. However, when I try the code below I receive the error "TypeError: collection.updateOne is not a function"
router.post('/deletegroup', function(req, res) {
var db = req.db;
var collection = db.get('groupcollection');
var filter = {"groupname" : req.body.groupname};
var updates = { $set: {"deleted" : true} };
collection.updateOne(filter, updates, function(err) {
if (err) {
// If it failed, return error
res.send("There was a problem deleting the group from the database.");
}
else {
// And forward to success page
res.redirect("grouplist");
}
});
});
I've read the documentation on updateOne() for Node.js from mongoDB and I can't seem to figure out the reason for the error. Also, I am still very new to javascript/nodejs/mongo so I would greatly appreciate more informative answers!
The solution I came up with was using unique IDs for each group and instead of using updateOne() just using update() and having the unique ID as the query to make sure that I don't modify groups with the same name
I am using Parse as a service for my app, specifically the JavaScript SDK.
In my app I have a class that represents a user post in my app containing images and text.
For some reason occasionally when a new object is created by the user, the objectId assigned by parse sometimes causes errors with that particular post.
I get this in the console:
t.Error {code: 105, message: "invalid field name: 3qUHMBPCBs"}
the field name is the objectId assigned automatically by Parse when the user uploads their post.
Second time this has happened. I noticed when I removed that post, the error disappeared but, obviously I can't keep deferring to that method.
Updated, code used for the user post below
so, essentially theres functionality that allows a user to post an update to parse. When the user submits, this function is performed and an object is generated by Parse.
var sendThis = $('#resultImage').attr('src');
var parseFile = new Parse.File("mypic.jpg", {
base64: sendThis
});
var val = document.getElementById('statusupdateform').value;
var statusupdate = $('#statusupdateform').val();
var currentUser = Parse.User.current();
parseFile.save().then(function() {
var nameCurrent = currentUser.getUsername();
var cigarWall = new Parse.Object("cigarwall");
cigarWall.set("appuser", nameCurrent);
cigarWall.set("statusupdate", statusupdate);
cigarWall.set("imagefile", parseFile);
cigarWall.save({
success: function() {
$('#uploadBtn').removeClass('tapActive');
var postupdate = cigarWall.get('statusupdate');
//$('#fileselect').attr('data-change', 'false');
$('#statusInnerWrapper').removeClass('slideLeft');
location.reload();
},
error: function() {
alert("upload failed. please try again!");
}
});
});
I Had a bad line of code in my Query function for one of the Parse classes. I Was unnecessarily querying against the objectId column.
I have a PFObject that has an array key. I can successfully call addObject: on this PFObject, and can confirm that the object has been added to the array key properly using an NSLog. However, when I try to save the PFObject to Parse, even though it says everything went successful, the changes are not shown in the Data Browser.
I have tried everything, and can even get this to work in an older version of my app, but for some reason it will not work anymore.
I posted another StackOverflow question about this here
The only response I got were some comments saying that I should trigger a "before save" function and log everything via Cloud Code. The problem is I don't know javascript, and I've been messing around with Cloud Code and nothing's happening.
Here is the code I am executing in my app:
[self.message addObject:currentUsersObjectId forKey:#"myArrayKey"];
And then I am using saveInBackgroundWithBlock:
I need to alter Cloud Code so that it will check the self.message object's "myArrayKey" before saving and log the results.
Edit 2:
Here is how I create currentUsersObjectId:
NSString *currentUsersObjectId = [[NSString alloc]init];
PFUser *user = [PFUser currentUser];
currentUsersObjectId = user.objectId;
Edit 3:
Here is the save block
[self.message saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (error) {
NSLog(#"An error has occurred.");
}
}];
Edit 4:
After adding Timothy's cloud code, the saveInBackgroundWithBlock: now does not successfully complete. Instead an error occurs, and the error object NSLogs as `"Error: Uncaught Tried to save an object with a pointer to a new, unsaved object. (Code: 141, Version: 1.2.17)" and also as:
Error Domain=Parse Code=141 "The operation couldn’t be completed. (Parse error 141.)" UserInfo=0x15dc4550 {code=141, error=Uncaught Tried to save an object with a pointer to a new, unsaved object.} {
code = 141;
error = "Uncaught Tried to save an object with a pointer to a new, unsaved object.";
}
Here is my complete Cloud Code file after adding Timothy's code:
Parse.Cloud.define('editUser', function(request, response) {
var userId = request.params.userId;
//newColText = request.params.newColText;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
var currentUser = request.user;
var relation = user.relation("friendsRelation");
relation.add(currentUser);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
Parse.Cloud.beforeSave("Messages", function(request, response) {
var message = request.object;
// output just the ID so we can check it in the Data Browser
console.log("Saving message with ID:", message.id);
// output the whole object so we can see all the details including "didRespond"
console.log(message);
response.success();
});
// log the after-save too, to confirm it was saved
Parse.Cloud.afterSave("Messages", function(request, response) {
var message = request.object;
// output just the ID so we can check it in the Data Browser
console.log("Saved message with ID:", message.id);
// output the whole object so we can see all the details including "didRespond"
console.log(message);
response.success();
});
After much back and forth, I'm stumped as to why this isn't working for you. As for logging in Cloud Code, if you follow the guide on adding code you can add the following to your main.js and deploy it:
Parse.Cloud.beforeSave("Messages", function(request, response) {
var message = request.object;
// output just the ID so we can check it in the Data Browser
console.log("Saving message with ID:", message.id);
// output the whole object so we can see all the details including "didRespond"
console.log(message);
response.success();
});
// log the after-save too, to confirm it was saved
Parse.Cloud.afterSave("Messages", function(request, response) {
var message = request.object;
// output just the ID so we can check it in the Data Browser
console.log("Saved message with ID:", message.id);
// output the whole object so we can see all the details including "didRespond"
console.log(message);
response.success();
});
With those in place you have plenty of server-side logging that you can check.
I am adding my own answer in addition to Timothy's in case anyone else is having a problem similar to this. My app uses the following library to allow parse objects to be stored using NSUserDefaults: https://github.com/eladb/Parse-NSCoding
For whatever reason, after unarchiving the parse objects, they are not able to be saved properly to the Parse database. I had to query the database using the unarchived one's objectId and retrieve a fresh version of the object, and then I was able to successfully make changes to and save the retrieved object.
I have no idea why this is happening now. I have never had any problems until about two weeks ago when I tried to deploy a new version of my cloud code, and if I remember correctly, Parse wanted me to update the Parse SDK or the Cloud Code version before I could deploy it.
These changes must not be compatible with these categories.
For each User object, I have an attribute called "trueFriends" where it contains an array of userIds. I would like to modify an user's list of "trueFriends" every time a friend is added, and am using the following Cloud Code function:
Parse.Cloud.define('editUser', function(request, response) {
var userId = request.params.userId,
trueFriends = request.params.trueFriends;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
user.add('trueFriends', trueFriends); //<-- If I change to "true_friends", this code works
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
I then call the function normally from my iOS app:
[PFCloud callFunctionInBackground:#"editUser" withParameters:
#{#"userId": userToAdd.objectId,
#"trueFriends": self.currentUser.username}
block:^(id object, NSError *error) {
}];
However, I get the error "Uncaught Tried to save an object with a pointer to a new, unsaved object." As per the comment in the Cloud code, if I change the code from "trueFriends" to "true_friends", it then no longer gives this error and everything saves successfully. I am unsure how to resolve the situation, despite looking at similar questions - thanks for the help!
So I am building an app, and in this app users will be able to go to each others' profile, and essentially like their profile. I am calling these likes compliments. This requires the current user to be able to access the selected users information to update the compliment count. So in order to implement this I am using Parse.com's cloud code.
My code looks like:
Parse.Cloud.define("complimentCounter", function(request, response) {
Parse.Cloud.useMasterKey();
var User = Parse.Object.extend("User");
var user = new User();
var user.id = request.params.userId;
var increment = request.params.increment;
user.increment = ("complimentsValue", increment);
user.save(null, {
success: function(user) {
response.success(true);
},
error: function(user, error) {
response.error("Could not compliment.");
}
});
});
However when I run it I get the error "Unexpected token . in main.js:8", and when I take that "." out it only returns the error of the function and not the success. Can someone please guide me in the right direction, and let me know what the issue is here? Thanks!
The increment() function is documented here.
The correct way to call it is:
// increment by 1
user.increment("keyName");
// increment by a number in a variable (yes you can use negative numbers too)
var increaseAmount = -5;
user.increment("keyName", increaseAmount);
You're reading a value, which seems to mean you want to increase the count by more than one, so the 2nd syntax is what you want.
Unfortunately you're calling it incorrectly, just take the = out of your line so it reads as follows:
user.increment("complimentsValue", increment);