Javascript query response from Parse.com - javascript

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.
}
});
}

Related

Can't Store and Retrieve From Chrome Storage

First of all, I apologize if this question sounds similar to others. I've done a lot of research and I guess I can't piece together my situation and issues other people have with this API.
I am creating an chrome app that basically demonstrates the ability to store and retrieve data from the Chrome Storage API. Once I'm comfortable doing this, I can implement this in a larger application I'm making.
However, I can't seem to get the basic app working. Here's the relevant code:
"storage.js"
function Store(key,data) {
console.log("Data: " + data);
chrome.storage.local.set({ key: data }, function () {
console.log("Secret Message Saved!");
});
}
function Retrieve() {
chrome.storage.local.get(function (data) {
console.log("The data stored is:" + data);
});
}
"master.js" (main script)
var myKey = "secretMessage";
var myData = "Pssst!";
Store(myKey, myData);
Retrieve(myKey);
console.log("Done!");
I'm at a loss. The output I get is:
Data: Pssst!
Done!
Secret Message Saved!
The data stored is:[object Object]
It appears that either I'm storing wrong or retrieving wrong.
I've looked through the documentation. Maybe I'm just not understanding the concept of the API and what it is able to store and retrieve. I'm fairly new to coding in the javascript language. Any help would be much appreciated!
Thanks!
First,
chrome.storage.local.set & chrome.storage.local.get
are asynchronous methods, you have to wait till chrome.storage.local.set stores data in storage, then you should call chrome.storage.local.get.
Second,
chrome.storage.local.get is returning an object. You can view object by using .toString() or JSON.stringify(data)
function Store(key,data, callback) {
console.log("Data: " + data);
chrome.storage.local.set({ key: data }, function () {
console.log("Secret Message Saved!");
callback(true);
});
}
function Retrieve(success) {
chrome.storage.local.get(function (data) {
console.log("The data stored is:" + JSON.stringify(data));
});
}
var myKey = "secretMessage";
var myData = "Pssst!";
Store(myKey, myData, Retrieve);
console.log("Done!");
I've used this callback method without a problem.
function loadSelectedStyle(){
chrome.storage.local.get('defaultColorSet', function (result) {
console.log(result.defaultColorSet);
defaultColors(result.defaultColorSet);
});
}
If you just write 'result' to the console log, you can see the entire object, by adding the key to result you get the data.

Parse.com query.equalTo error processing

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);
}
});

Requesting Function Response in another function

I have those two functions where i call "http" from "Count" the "http" return promise. I want to use the return value of "http" in "Count". What I receive now is Undefined !!!
What I'm missing ?
Count Function :
Parse.Cloud.define('count', function(request, response) {
var query = new Parse.Query('MyS');
query.equalTo("Notify", true);
query.notEqualTo ("MainEventCode", '5');
query.find({
success: function(results) {
Parse.Cloud.run('http', {params : results}).then(
function(httpResponse) {
console.log('httpResponse is : ' + httpResponse.length);
response.success('Done !');
}, function(error) {
console.error(error);
});
},
error: function(error) {
response.error(error);
}
});
});
http Function :
Parse.Cloud.define('http', function(request, response) {
var query = new Parse.Query(Parse.Installation);
.
.
.
}
Relying on calling your own functions through an external interface is not a very good practice.
Now that you've realized you're going to need the same code for a different purpose, you should take the time to refactor your code such that you don't need to call the 'http' handler through Parse.Cloud.run():
function doHttp(params) {
// original implementation here
}
Parse.Cloud.define('http', function(request, response) {
doHttp(request.params)
.then(response.success)
.fail(response.error);
}
Parse.Cloud.define('count', function(request, response)) {
var query = new Parse.Query('MyS');
query.equalTo("Notify", true);
query.notEqualTo ("MainEventCode", '5');
query.find()
.then(doHttp) // doHttp will receive the results from `query` as its parameter
.then(function(httpResponses) {
// httpResponses is an array-like object as per the other question:
httpResponses = Array.prototype.slice.call(httpResponses);
httpResponses.forEach(function (response) {
console.log('httpResponse is : ' + response.length);
});
}).fail(response.error);
}
I've taken a look at the other question and as far as the implementation of count goes, I believe you're missing the point that 'http' is returning arguments, which is only an Array-like object.
This should be okay if Parse.Cloud.run runs your function on another virtual machine, but this kind of weird behaviour is another symptom of not refactoring and reusing your code through an external call (an HTTP request inside their infrastructure with JSON passing! It might greatly reduce performance and count against your requests/second quota). If Parse instead does some magic to call your function directly as if it was defined on the same environment, you're going to have problems with it not being an actual Array.
You should modify that function to return a proper array if possible. Parse CloudCode has a version of the Underscore library:
// on http
var _ = require('underscore');
Parse.Promise.when(promises).then(function() {
var results = _.toArray(arguments) // equivalent to Array.prototype.slice above
response.success(results);
}
I think what you're asking is how to use an externally callable cloud function as a step in a bigger cloud procedure. Here's how to do it: (#paolobueno has it essentially correct, with only a couple mistakes in the details).
First, let's convert that 'http' cloud function to a regular JS function. All we need to do is factor out the request and response objects. (#paolobueno has a very good idea to use underscorejs, but I won't here because its another new thing to learn).
// for each object passed in objects, make an http request
// return a promise to complete all of these requests
function makeRequestsWithObjects(objects) {
// underscorejs map() function would make this an almost one-liner
var promises = [];
for (var i = 0; i < objects.length; i++) {
var object = objects[i];
promises.push(makeRequestWithObject(object));
}
return Parse.Promise.when(promises);
};
// return a promise to do just one http request
function makeRequestWithObject(object) {
var url = 'http://185.xxxxxxx'+ object +'&languagePath=en';
return Parse.Cloud.httpRequest({ url:url });
}
It looks like you want the updated cloud function -- rather than use params from the client -- to first make a query and use the results of that query as parameters to the http calling function. Here's how to do that. (Again, using #paolobueno's EXCELLENT practice of factoring into promise-returning functions...)
// return a promise to find MyS instances
function findMyS() {
var query = new Parse.Query('MyS');
query.equalTo("Notify", true);
query.notEqualTo ("MainEventCode", '5');
return query.find();
}
Now we have everything needed to make a clear, simple public function...
Parse.Cloud.define('count', function(request, response) {
findMyS().then(function(objects) {
return makeRequestsWithObjects(objects);
}).then(function(result) {
response.success(result);
} , function(error) {
response.error(error);
});
});

Azure mobile service - get row(s) based on matching string/substring value

I am trying to read results from JavaScript azure mobile service and I want to return items with a specific values. I am using getTable(‘’).where.(‘’).read(‘’) to check if one of the returned json value match a specific pattern as shown in this post:
Here is my client side script:
function getSP() {
var spUser = client.getTable("User").where(function (contains) {
return this.extraname.indexOf(contains) > 0;
}, "Eyad").read().done(function (results) {
alert(JSON.stringify(results));
}, function (err) {
alert("Error: " + err);
});}
And the request URL generated from client:
https://XYZ.azure-mobile.net/tables/User?$filter=(indexof(extraname,'Eyad') gt 0)
But the code above return an empty [] object form the service, while performing the same operation without the where() check clearly returns my intended value:
What am I doing wrong? How can I return the row(s) where the returned "extraname" contains the substring "Eyad"?
NOTE: I also have a custom read script on the service side, and you can see the "extraname" value is hardcoded for testing purposes:
function read(query, user, request) {
request.execute({
success: function(results) {
var now = new Date();
results.forEach(function(item) {
console.log(item.userjsondata);
item.extraname = "Eyad";
});
request.respond(); //Writes the response
}
});
}
If you're generating a new column dynamically, then there's no way to - directly - use a $filter clause to filter the results based on that value. Notice that you can write arbitrary code to calculate that value, so the mobile service runtime has no way to know what value it will end up generating, and cannot perform a filter based on that.
There are a couple of workarounds for your solution: if possible, you can send a where clause with the same expression that you use to generate the value. In some cases the service will accept that expressions in the $filter clause as well. That has the drawback that you'll end up with the same logic in two different places, and there's a big chance that you'll change one and end up forgetting to change the other.
Another alternative is to pass the parameter for which you want to query the generated property not in the $filter parameter (i.e., don't use the where function, but pass the parameters inside the read call. Those parameters will be passed to the read script in the request.parameters object, and you can add your logic to filter based on that value after you're done reading from the database (see below).
Client:
var spUser = client.getTable("User").read({mustContain: "Eyad").done(function (results) {
alert(JSON.stringify(results));
}, function (err) {
alert("Error: " + err);
});}
Service:
function read(query, user, request) {
var mustContain = request.parameters.mustContain;
request.execute({
success: function(results) {
var now = new Date();
var filteredResults = [];
results.forEach(function(item) {
console.log(item.userjsondata);
item.extraname = "Eyad";
if (item.extraname.indexOf(mustContain) >= 0) {
filteredResults.push(item);
}
});
request.respond(200, filteredResults); //Writes the response
}
});
}
change your comparison from this:
return this.extraname.indexOf(contains) > 0;
to this:
return this.extraname.indexOf(contains) >= 0;
A matched string can be (in your case, always) found in the first index. Therefore you have to use greater than OR equal to operator to handle that case.

How to fetch an object in Parse Cloud Code

I am working on a parse cloud code function which performs a query and filters the results afterwards. These are my first lines of code written in JavaScript, so I have no clue how to solve the following problem.
The problem is, that my filter predicate needs some elements stored in the someArray variable. All elements of someArray aren't fetched yet. But fetching an an Parse.Object is a asynchronous call, so I have no chance to return trueor false expected by filter().
How can I solve this problem?
Or I am misinterpreting the fact, that when I don't fetch the arrayElement
console.log("arrayElement with name: ".concat(typeof(arrayElement), arrayElement.get("name")));
prints
arrayElement with name:objectundefiend
although I know that Object represented by arrayElment has a name-column which is always defined?
//The cloud code
Parse.Cloud.define("search", function(request, response) {
var query = new Parse.Query("Location");
query.withinKilometers("gps", request.params.searchLocation, request.params.searchRadius / 1000);
query.find({
success: function(results) {
// results is an array of Parse.Object.
var locations = results.filter(function(location) {
console.log("Location with name: ".concat(location.get("name")));
var someArray = location.get("someArray");
if (someArray instanceof Array) {
console.log("The array of this location has ".concat(someArray.length, " elements."));
someArray.forEach(function(arrayElement) {
arrayElement.fetch().then(
function(fetchedArrayElement) {
// the object was fetched successfully.
console.log("arrayElement with name: ".concat(typeof(fetchedArrayElement), fetchedArrayElement.get("name")));
if (menuItem) {};
return true;
},
function(error) {
// the fetch failed.
console.log("fetch failed");
});
});
}
});
response.success(locations);
},
error: function(error) {
// error is an instance of Parse.Error.
response.error(error);
}
});
});
some useful links:
Parse JavaScript SDK API
Parse Cloud Code Guide
If I'm reading this right, you've got an array column of Parse Objects. You should use the include method on your query so that the objects are fetched in the initial query.
query.include('someArray');
I don't think you'll want to use a filter, and should take a look at the Promises documentation here: https://parse.com/docs/js_guide#promises
You're right that since it's asynchronous, you need to wait for everything to be done before calling response.success which doesn't currently happen in the code. Promises and defining your own async functions that use Promises is a great way of chaining functionality and waiting for groups of functions to complete before going forward.
If all you wanted to do what include that column, the whole thing should just be:
Parse.Cloud.define("search", function(request, response) {
var query = new Parse.Query("Location");
query.include('someArray');
query.withinKilometers("gps", request.params.searchLocation, request.params.searchRadius / 1000);
query.find().then(function(results) {
response.success(locations);
}, function(error) {
response.error(error);
});
});

Categories

Resources