Cannot create a pointer to an unsaved ParseObject - javascript

I am having troubles referring to a "User" object from inside a query. I have the following code:
Parse.Cloud.define("getTabsBadges", function(request, response) {
var UserObject = Parse.Object.extend('User');
var user = new UserObject();
user.id = request.params.userId;
// Count all the locked messages sent to the user
var receivedMessagesQuery = new Parse.Query('Message');
receivedMessagesQuery.equalTo('status', 'L');
receivedMessagesQuery.equalTo('toUser', user); // THIS LINE GENERATES THE ERROR
receivedMessagesQuery.count({
// more code here
});
});
I call the function using CURL but I always get the following error:
{"code":141,"error":"Error: Cannot create a pointer to an unsaved
ParseObject\n at n.value (Parse.js:14:4389)\n at n
(Parse.js:16:1219)\n at r.default (Parse.js:16:2422)\n at e.a.value
(Parse.js:15:1931)\n at main.js:9:25"}
I am using the exactly same code in another project, the only difference is that instead of counting objects I find them and its works correctly. I have also verified that the tables have a column type of Pointer<_User> in both projects. What's causing the problem?

The error message Cannot create a pointer to an unsaved means that you are trying to use an object which does not exist in the Parse DB.
With var user = new UserObject();, you're creating a new user object. You cannot use it in a query until you save it to Parse.
Instead of creating a new User object and setting it's objectId, do a query for the User object. See code below:
Parse.Cloud.define("getTabsBadges", function(request, response) {
var UserObject = Parse.Object.extend('User');
var query = new Parse.Query(UserObject);
query.get(request.params.userId, {
success: function(user) {
// Count all the locked messages sent to the user
var receivedMessagesQuery = new Parse.Query('Message');
receivedMessagesQuery.equalTo('status', 'L');
receivedMessagesQuery.equalTo('toUser', user); // THIS LINE GENERATES THE ERROR
receivedMessagesQuery.count({
// more code here
});
},
error: function(error) {
// error fetching your user object
}
});
});

Your request.params.userId may be undefined or null, which causes this error.
Your query constraints cannot compare the Parse Object that is created without data (createWithoutData()) using undefined or null as its objectId.

Related

Basic Parse query to access a field inside a pointer object in JavaScript

I have a table called "Current1", which I am saving user's object as pointer like this:
When I click on this pointer I direct to _User table. Now I am trying to do very simple query. I need to access to username inside user pointer and later update something in _User table.
My problem is now to access 'username' in '_User' table by using a pointer:
var aveGame2 = Parse.Object.extend("Current1");
var query2 = new Parse.Query(aveGame2);
query2.include("user");
query2.find({
success: function(results) {
for (var i = 0; i < results.length; i++)
{
var object = results[i];
//....
var user = object.get('user');
var username = user.get('username'); //<--Error is pointing to this line
//More operation
if(True)//Some conditions
{
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.equalTo("username", username);
// Get the first user which matches the above constraints.
query.first({
success: function(anotherUser) {
anotherUser.set("prize", 10);
// Save the user.
anotherUser.save(null, {
success: function(anotherUser) {
// The user was saved successfully.
response.success("Successfully updated user.");
},
error: function(gameScore, error) {
// The save failed.
// error is a Parse.Error with an error code and description.
response.error("Could not save changes to user.");
}
});
},
error: function(error) {
response.error("Could not find user.");
}
});
Error:
[Error]: TypeError: Cannot call method 'get' of undefined
at e.query2.find.success
After hours of checking each fields I realised I have not set ACL for _User table as Public read. This might help someone else.

Parse Cloud Code - Only Retrieve Certain Columns Before Sending Response.

I currently have this cloud code to retrieve all the users that have a relation with the current user. I have to first find the current user then query the "Friends" column hence the relational query step.
The line response.success(results) returns all the attributes of all of the current user's friends. I only want a few of the columns that belong to these friends, not every single thing they saved when signing up.
Parse.Cloud.define("getFriends", function(request, response) {
var userId = request.params.UserKey;
var query = new Parse.Query(Parse.User);
query.ascending("updatedAt");
query.get(userId, {
success: function(foundCurrentUser) {
var currentUser = foundCurrentUser;
var relation = currentUser.relation("Friends");
var getRelationQuery = relation.query();
getRelationQuery.find().then(function(results) {
response.success(results);
});
},
error: function(error) {
response.error(error);
}
});
});
I am using swift to to use the response, I am not sure that if I need to tweak the swift code but will provide it anyway.
func LoadCarpoolersFromParse(Success:(object:AnyObject)->(),Failure:(error:NSError)->())
{
let params = NSMutableDictionary()
params.setObject(PFUser.currentUser()!.objectId!, forKey: "UserKey")
PFCloud.callFunctionInBackground("getCarpoolers", withParameters: params as [NSObject : AnyObject], block: {
(response:AnyObject?, error: NSError?) -> Void in
if error == nil {
Success(object: response!)
}
else{
Failure(error:error!)
}
})
}
}
You can do it by using select method of Parse.Query, make the following changes in your cloud code
Parse.Cloud.define("getFriends", function(request, response) {
var userId = request.params.UserKey;
var query = new Parse.Query(Parse.User);
query.ascending("updatedAt");
query.select("name","phone"); // replace with your required fields

Obtain Data from two parse classes based on column in one table

I have to Parse Classes in my data browser, 'Details' and 'Content'. The 'Details' class has the following --> 'objectId', 'uuid' and 'proximity'. The 'Content' class has 'objectId', 'descId' and 'offer'.
I have created a web UI using the Javascript SDK so when the user enters the uuid, proximity and offer, uuid and proximity get stored in the 'Details' class, on success I then get the objectId of the newly created object. I then store that objectId in the 'Content' class under descId and the offer that was inputted by the user.
My problem is I have a html table that I need to populate, so I need to pull the data from both classes. The uuid and proximity from 'Details' and the offer from 'Content' so I need to do this in one query. This is my reason for storing the 'Details' objectId in the 'Content' class as a type of foreign key.
I am stuck at this cross roads and have tried include etc but I am just trying things and I'm not sure what I need to do. If anyone can help, perhaps show me a sample, I'd greatly appreciate it
Here is my js save code:
//Creating Beacon Content Parse Object
var iBeaconContent = Parse.Object.extend("Content");
var beaconContent = new iBeaconContent();
//Creating Object to save to iBeacon Description Table
var iBeaconDescription = Parse.Object.extend("Details");
var beaconDescription = new iBeaconDescription();
beaconDescription.set("uuid", tdUuid.children("input[type=text]").val().toString());
beaconDescription.set("proximity", parseInt(tdProximity.children($('prox')).val().toString()));
beaconDescription.save(null, {
success: function(beaconDescriptionObject) {
var query = new Parse.Query("Details");
query.equalTo("uuid", tdUuid.children("input[type=text]").val().toString());
query.find({
success: function(results) {
objectId = results[0].id;
beaconContent.set("descId", objectId);
beaconContent.set("offer", tdOffer.children("input[type=text]").val().toString());
beaconContent.save(null, {
success: function(object) {
document.location.reload(true);
}, error: function(beaconContent, error) {
}
});
}
});
},
error: function(error) {
}
});
NEW JAVASCRIPT
var BeaconDetail = Parse.Object.extend("Details");
var BeaconContent = Parse.Object.extend("Content");
var innerQuery = new Parse.Query(BeaconDetail);
innerQuery.exists("descId");
var query = Parse.Query(BeaconDetail);
query.matchesQuery("objectId", innerQuery);
query.find({
success:function(beaconContent){
alert("Success----lenght: " + beaconContent.length);
}
})
Sound like you need to use a compound query or relationship query. Here are some links
https://docs.parseplatform.org/js/guide/#relational-queries
https://docs.parseplatform.org/js/guide/#compound-queries
https://parse.com/questions/compound-relational-queries
An example of a query from two classes is as follows
It would also be good to see the code, would help give a more relative answer.
CODE
var lotsOfWins = new Parse.Query("Player");
lotsOfWins.greaterThan("wins", 150);
var fewWins = new Parse.Query("Player");
fewWins.lessThan("wins", 5);
var mainQuery = Parse.Query.or(lotsOfWins, fewWins);
mainQuery.find({
success: function(results) {
// results contains a list of players that either have won a lot of games or won only a few games.
},
error: function(error) {
// There was an error.
}
});
If I understand correctly, your Content class contains a pointer to your Details class in the descId property, and you want to be able to query based on some Details fields and return both objects?
NOTE: I must point out that descId is a very poorly named property that will just cause confusion. If it is a pointer, just give it a name like desc, leave off the Id suffix.
Anyway, if that is what you want:
var query = new Parse.Query("Content");
var uuid = tdUuid.children("input[type=text]").val().toString();
var proximity = parseInt(tdProximity.children($('prox')).val().toString());
// consider logging those two variable to confirm they're what you want
// query properties of a pointer
query.equalTo("descId.uuid", uuid);
query.equalTo("descId.proximity", proximity);
// include the pointer in the output
query.include("descId");
query.find({
success: function(beaconContent) {
alert("Success -- length: " + beaconContent.length);
// sample output of first result:
var content = beaconContent[0];
var detail = content.get("descId");
console.log("uuid", detail.get("uuid"));
console.log("proximity", detail.get("proximity"));
console.log("offer", content.get("offer"));
}
});

New object not appearing in Parse data browser

I want a new userCategory object to be created when a user signs up in my iOS app. I figured the best way to do this would be to call a Parse cloud code function once signup is successful that triggers the creation of the object. When I check Parse's databrowser however, the new user is created, but a new userCategory associated with the user isn't.
objective-c code:
// Sent to the delegate when a PFUser is signed up.
- (void)signUpViewController:(PFSignUpViewController *)signUpController didSignUpUser:(PFUser *)user {
[self dismissViewControllerAnimated:YES completion:NULL];
[PFCloud callFunctionInBackground:#"userCategoryCreate"
withParameters:#{}
block:^(NSNumber *ratings, NSError *error) {
if (!error) {
//userCategory created
}
}];
}
Cloud Code:
Parse.Cloud.define("userCategoryCreate", function(request, response) {
// Simple syntax to create a new subclass of Parse.Object.
var UserCategory = Parse.Object.extend("UserCategory");
// Create a new instance of that class.
var userCategory = new UserCategory();
response.success("userCategory succesfully created!");
});
You should do something similar to:
// Simple syntax to create a new subclass of Parse.Object.
var UserCategory = Parse.Object.extend("UserCategory");
// Create a new instance of that class.
var userCategory = new UserCategory();
// set necessary fields for the new entry row ( if needed )
userCategory.set("categoryName","categoryFoo1");
...
..
.
// Then save the object
userCategory.save().then(function(savedObj){
response.success("userCategory succesfully created!");
},function(saveError){
response.error("Unable to create this object");
});
Hope it helps

Unable to retrieve required object from parse.com User class using javascript

I'm using the JavaScript SDK with I'm using parse.com.
The below code is meant to select the user thats currently logged in, then retrieve their "username" from the "User" class and show it in the console log.
Parse.initialize("XXXX", "XXXX");
var currentUser = Parse.User.current();
var query = new Parse.Query(Parse.User);
query.equalTo(currentUser);
query.find({
success: function(theuser) {
console.log(username);
}
});
UPDATE, BASED ON THE ANSWER BELOW I TRIED
var currentUser = Parse.User.current();
var user = currentUser.get("username");
var user = currentUser.get("gender");
console.log(user);
console.log(gender);
but now get Uncaught ReferenceError: gender is not defined ?
At the moment I'm getting the following error.
POST https://api.parse.com/1/classes/_User 400 (Bad Request)
parse-1.2.17.min.js:1 t._ajax parse-1.2.17.min.js:1 t._request
parse-1.2.17.min.js:1 t.Query.find parse-1.2.17.min.js:3 (anonymous
function)
This seems to say it cannot find the User class, but you can see from the screen shot this does exist. Can anyone help me with what the issue is here?
With "var currentUser = Parse.User.current(); " you already have the current user object. Don't query for it. Just get the value from the object.
One problem is here:
var user = currentUser.get("username");
var user = currentUser.get("gender"); //you also named this var 'user' instead of 'gender'
change this to:
var user = currentUser.get("username");
var gender = currentUser.get("gender");

Categories

Resources