Parse.com query.equalTo error processing - javascript

I'm trying to query a Parse.com database to see if a certain field is available. I am then looking to do certain actions depending on whether or not the variable is present in the database.
Here is the full production function:
function getProduct() {
var Products = Parse.Object.extend("Products");
ProductEAN = 76130347394081;
output = "";
var query = new Parse.Query(Products);
query.equalTo("EANBarcode", ProductEAN );
query.find({
success: function(results) {
var no = results[0].get("EANBarcode");
var title = results[0].get("Name");
output += "[" + no + "] " + title;
console.log( "Output is: " + output );
},
error: function(error) {
alert(error.message);
}
});
}
If the ProductEAN is present, then the success function works as intended. If it is not present, rather than the error function running, I get a console output saying the following:
"Uncaught TypeError: Cannot read property 'get' of undefined"
I am following this guide: https://www.youtube.com/watch?v=2TVmgEJfbno
I am at a bit of a loss as to why this would not work. Does anyone have any experience with this?

Error callback of find() method gets called only when there's an error in execution. In the case when ProductEAN is not present, it is still a successful query but with zero matching records. Which means it calls your success callback with results being an empty array. Hence results[0] is undefined , which explains the console error output.
You might want to change your success callback to verify for the results.length and make decision appropriately. Something like this :
query.find({
success: function(results) {
if(results.length > 0){
var no = results[0].get("EANBarcode");
var title = results[0].get("Name");
output += "[" + no + "] " + title;
console.log( "Output is: " + output );
}
else{
console.log('No matching records');
}
},
error: function(error) {
alert(error.message);
}
});

Related

How to get count of relation field in parse

GameScore object have one Relation field named Badges.
How I can get count of all objects in this relation in query:
var GameScore = Parse.Object.extend("GameScore");
var query = new Parse.Query(GameScore);
query.equalTo("playerName", "Dan Stemkoski");
query.find({
success: function(results) {
alert("Successfully retrieved " + results.length + " scores.");
// Do something with the returned Parse.Object values
for (var i = 0; i < results.length; i++) {
var object = results[i];
alert(object.id + ' - ' + object.get('playerName'));
}
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
I need something like:
object.Badges.count
or
object.Badges.length
A Parse.Relation object is actually a query description that will return the objects in that relation, so for this case you'd need to run another query for each GameScore:
query.find().then(function (gameScores) {
alert("Successfully retrieved " + gameScores.length + " scores.");
var countPromises = gameScores.map(function (gs) {
// the following executes a count() query, which is severely penalized by Parse
return gs.get('Badges').query().count()
.then(function (count) {
// this extra step is to add the retrieved count as an extra property to the GameSccore object,
// instead of returning only the counts
gs.count = count;
return gs;
});
});
return Parse.Promise.when(countPromises);
}).then(function () {
var gameScoresWithBadgeCount = Array.prototype.slice.call(arguments);
}).fail(function(error) {
alert("Error: " + error.code + " " + error.message);
});
This causes a lot of extra round trips (I assume you're on a browser environment because of alert()), and calls count() queries which are additionally limited by Parse.
What I can recommend you is to keep a count cache as an extra field on the GameScore class, and update it accordingly through CloudCode hooks. Alternatively, you can try to avoid the Relation and make the equivalent using an Array field if possible, through which you can always include the related Badges if needed or get their count without querying for them at all!
Sadly, tougher than one would hope. It requires another asynch trip through the data, so your callback form can do it, but isn't really up to the job. Here it is with promises...
// return a promise that's fulfilled with a badges count for the passed GameScore
function badgeCountOfGameScore(gameScore) {
var relation = gameScore.get("Badges"); // it must have a relation col called Badges for this to work
return relation.query.find().then(function(results) {
return results.length;
});
}
Now your original function redone with promises (and underscore to better handle arrays)...
var _ = require("underscore");
function bunchOfBadgeCounts() {
var GameScore = Parse.Object.extend("GameScore");
var query = new Parse.Query(GameScore);
query.equalTo("playerName", "Dan Stemkoski");
return query.find().then(function(results) {
alert("Successfully retrieved " + results.length + " scores.");
var promises = _.map(results, function(object) {
return badgeCountOfGameScore(object);
});
return Parse.Promise.when(promises);
}).then(function() {
alert("Counts = " + JSON.stringify(_.toArray(arguments)));
}, function (error) {
alert("Error = " + JSON.stringify(error));
});
}

Destroying objects from Parse Cloud is unreliable

I'm trying to delete all objects in a class, but whenever I attempt to delete objects from a cloud function or job I get an inconsistent number of objects left over. The jobs always take under second, so I don't think that's the issue (working with under 100 objects anyway). I seem to always have a random number of objects left over and no errors. This is what I'm working with now.
Parse.Cloud.job("deletePosts", function(request, status) {
Parse.Cloud.useMasterKey();
var query = new Parse.Query("Posts");
query.find({
success: function(results) {
Parse.Object.destroyAll(results).then(function() {
console.log("Delete job completed.");
status.success("Delete job completed.");
});
},
error: function(error) {
console.log("Error in delete query error: " + error);
status.error("Error in delete query error: " + error);
}
});
});
When deleting objects in cloud code, use query.each instead of query.find to ensure that you delete all objects matching the query .
find has the query limitation of 100 objects returned by default (or up to 1000 if limit is used). Source
Below is an example of using a promise chain which calls destroy on each Post object. When all of the destroy promises have completed, the success status will be reached, and if any of the destroys fail then the error status will be reached.
Parse.Cloud.job("deletePosts", function(request, status) {
Parse.Cloud.useMasterKey();
var query = new Parse.Query("Posts");
query.each(function(post) {
return post.destroy();
}).then(function() {
console.log("Delete job completed.");
status.success("Delete job completed.");
}, function(error) {
alert("Error: " + error.code + " " + error.message);
status.error("Error: " + error.code + " " + error.message);
});
});

Javascript query response from Parse.com

I am doing a query from Parse.com through a Javascript function as below.
function doFunction () {
var query = new Parse.Query("english");
query.find({
success: function(results) {
alert (results)
},
error: function(error) {
// error is an instance of Parse.Error.
}
});
}
while I can see the length of query response by alerting results.length, I cant get what is inside the results. alert(results) shows only [object Object],[object Object]...
What is the response format, is it a JSON or an array? how can I get the values?
Thanks
Use console.log in your code:
function doFunction () {
var query = new Parse.Query("english");
query.find({
success: function(results) {
console.log(results);
},
error: function(error) {
// error is an instance of Parse.Error.
}
});
}
And then see in Developer Tools(F12) -> Console, what is being returned as response.
in javascript you can check objects with a console.log.
console.log is very flexible. It can take n-parameters and every type.
So you can mix up Strings and Objects seperated with a comma.
var myTestObject = { testString: "Hello World!" };
console.log("This is my test Object:", myTestObject);
//Output: This is my test Object: Object {testString: "Hello World!"}
While I agree with the above answers that console.log() is a good way to print out your objects, there are better ways to do this. Besides, I recommend that you always use an alert() function in your success and error blocks while in development.
This is because it is possible to have bugs in your code where requests are made to Parse.com an infinite number of times. Since Parse.com will charge you money when you make a certain number of requests per second, this could cause you to accidentally be charged by Parse.com against your wishes. If you are using console.log() and accidentally do this, you won't be aware of the bug unless you have the console open. However, if you use alert(), you will be prompted each time a success or failure call is made, and thus you will be able to prevent this issue.
Furthermore, you don't HAVE to use console.log() to see your data. You can simply call properties on the returned object (which is in JSON format), using the following:
query.find({
success: function(results) {
alert(results.get("propertyName"));
},
// error blocks and result of logic here
While object.id gives the object id I needed to use object.get('ephrase') to get other parameters.
function doFunction () {
var query = new Parse.Query("english");
query.find({
success: function(results) {
alert("Successfully retrieved " + results.length + " scores.");
// Do something with the returned Parse.Object values
for (var i = 0; i < results.length; i++) {
var object = results[i];
alert(object.id + ' - ' + object.get('ephrase'));
}
},
error: function(error) {
// error is an instance of Parse.Error.
}
});
}

JS (Using Parse for Storage) - Value Undefined for Some Reason

Okay, so today I was adding a new feature to my chat thing and I wanted it to whenever an admin typed /clearchat, it would clear the chat.
But then there is this weird bug that when I run getAllMessages(), it returns undefined. I tried printing the value it returns in the function, and that had a value!
Following is the code:
function getAllMessages() {
var Chat = Parse.Object.extend("message");
var query = new Parse.Query(Chat);
query.find({
success: function(message) {
console.log(message);
return message;
},
error: function(message, error) {
alert("Error: " + error.code + " " + error.message);
}
});
}
If you want to actually test it out, I edited the code a little and put it on JSFiddle (Click here).
(Of course, I made a new Parse project so my data wouldn't get hacked)
Any help would be highly appreciated!
Thanks,
Oliver
Ohhhhh
The query.find() function was asynchronous! So it was undefined at that time!

Parse error code 1 internal error when attempting to run a job

I have the following job I've created to clean out unneeded records. I've simplified the code below to troubleshoot the root cause, but with just this, over 80% of the times I run it fails to find anything due to Error code 1 "internal error":
Parse.Cloud.job('cleanStories', function(request, status) {
Parse.Cloud.useMasterKey();
var counter = 0;
var query = new Parse.Query('Story');
query.doesNotExist("username");
query.limit(1000);
query.find({
success: function(results) {
counter += results.length;
status.success(counter + " stories found.");
},
error: function(error) {
status.error(counter + " stories found. Error: " + error.code + " " + error.message);
}
});
});
I currently have about 568k records. This is down from almost 800k, which is when I started running this job to clean out records. It was usually running fine, but since has started erroring out very consistently. What am I doing wrong?
EDIT:
I have decreased the limit to 50 and it has a higher rate of success on executing. At 100 (default) it still regularly fails. Is there anyway I can get it back up to 1000 to get through the rest of the records faster?
This is based on a weak theory that smaller limits will help (if it really is a timeout issue, hopefully its a per query timeout and not a per job timeout, otherwise this idea won't help at all). But here's an idea how to do large find using limit/skip:
function findN(query, results) {
results = results || [];
query.skip(results.length);
return query.find().then(function(findResults) {
results = results.concat(findResults);
return (findResults.length === 0)? results : findN(query, results);
});
}
// to run this, build a query
var query = new Parse.Query("MyClass");
// qualify the query however you wish
// set any limit up to 1000, but our guess is that yours should be small
query.limit(20);
var results = [];
findN(query, results).then(function(r) {
console.log("found " + r.length + " rows");
// r will contain all of the rows matching the query, found 20 at a time
});

Categories

Resources