I'm just starting with Parse (developing with Corona SDK). I've had no problems with basic usage such as getting and uploading data, authenticating users etc.
I have had some trouble getting my head around Cloud Code though.
Here's what I'm after:
My User class has an array column called exclude. For each user it contains some objectId's of objects stored in another class called questions. On request, I would like Parse to return all questions whose objectId's are NOT inside current user's exclude array.
I could do it without cloud code, by just downloading the whole questions class content and filtering it on device, but I thought it would be more efficient to do it server-side.
So is this achievable via Cloud Code? Do you know any examples I could look at to understand how to do it?
Edit: I've tried this function. It does not return anything. (exclude has been changed to doneQuestions)
Parse.Cloud.define("getQuestions", function(request, response) {
var query = new Parse.query("Questions");
query.notContainedIn("objectId", user["doneQuestions"]);
query.find({
success: function(objects) {
console.log();
},
error: function(error) {
console.log("An error occured :(");
}
});
});
You can use the notContainedIn constraint:
query.notContainedIn("objectId", user["exclude"]);
Related
I am using the following JS code to retrieve seats details for all the subscriptions of my customers.
gapi.client.reseller.subscriptions.list()
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
},
function(err) { console.error("Execute error", err); });
However, it's returning all of their other information as well. How can I customize it so that it only returns the number of seats?
Google APIs has a standard parameter called fields that allows you select which fields are included in the response (see documentation on Docs API).
In Google API Client Library for JavaScript (aka gapi) you can simply add the parameters in an object when making a request. In your case this should work:
gapi.client.reseller.subscriptions.list({
fields: [
'nextPageToken',
'subscriptions/subscriptionId',
'subscriptions/seats/numberOfSeats',
].join(',')
})
It's important to keep all fields that you need including control fields like nextPageToken. You can read more about the format used here.
I am trying to access properties located on the User object for the current user in a cloud code function. The current user is passed to the cloud code function and available at request.user. The Cloud Code is deployed to Heroku using parse-cloud-express.
When the request first arrives, it does not contain the user data other than the id.
So I tried performing a fetch to get the latest data:
Parse.Cloud.define("functionName", function (request, response) {
request.user.fetch().then(function (user) {
console.log(util.inspect(user));
});
});
But it outputs the same data and does not seem to include the User object's properties.
2015-12-15T01:19:08.830880+00:00 app[web.1]: { _objCount: 1, className: '_User', id: 'dKqZMSRgDc' }
I also tried performing a query on the user id, but receive the same result.
var userQuery = new Parse.Query(Parse.User);
userQuery.get(request.user.id).then(function (user) {
console.log(util.inspect(user));
});
How do I get the properties of the User object?
The problem was not with getting data for the User object, but the way I was logging it. It seems that the data is not available from the object itself, so the output from util.inspect was correct, but does not include any properties. (I'm guessing the internals of the Parse framework manages this in another way.)
I replaced with console.log(user.toJSON()) and can now see the expected data for the user.
I am using Parse for my backend and want to search for existing friend requests and update those instead of creating new ones (if there is already an existing one).
I thought I figured out how to do it but when I submit new friend requests they get created as new objects instead of updating the old one, even though I found an existing request.
Here is the code I am using:
Parse.Cloud.beforeSave("FriendRequest", function(request, response) {
//search for an existing friend request with the same "from" and "to"
var query = new Parse.Query("FriendRequest");
query.equalTo("from", request.object.get("from"))
.equalTo("to", request.object.get("to"));
query.find({
success: function(results) {
if(results.length > 0)
{
var result = results[0];
//the new request id is undefined as expected
console.log("request id: " + request.object.id);
//the result id is valid for an object in the db as expected
console.log("result id: " + results[0].id);
//set the id of the request to the id of the existing db object
request.object.id = results[0].id;
//the valid id is now in the request object id
console.log("request id: " + request.object.id);
//after response.success, the database shows a new entry
//with a different id
//instead of updating the existing entry
response.success();
}
}
});
});
There isn't a lot going on here. The query does come back successful with the correct entry in the database. I can confirm that I get the correct objectId for the existing item in the database. Any thoughts or ideas are appreciated!
You can't manually set the objectId of an object.
If you want beforeSave to NOT create a new object (which is what you're about to do when beforeSave is called), you need to manually update the existing object and then respond with a failure. If you respond with response.success(), the object will be saved normally.
In your code, you don't seem to make any changes to the existing object. All you really need to do is to return response.error (https://parse.com/docs/cloud_code_guide#functions-onsave)
Of course, you should also handle this in your code somehow. Either by alerting the user, or handling it silently.
However; why does your code attempt to save a new friend request if one already exist? Your app should know that one exists and disable the friend request button or whatever the UI offers.
Ok, in my application, I have extra information sent with the data, which the Sencha docs define as metadata. If there was an error retrieving data, say for a grid, i want the server to be able to tell the client to inform the user that it was unable to complete the request. But I want to do this for EVERYTHING, and not have to redefine a callback to check on every store in my application. Is there a way to do this? Or am I trying to do this all wrong? Also, how can I go about utilizing the JSON Reader without using stores or models? That way I can do the same thing, intrepting server instructions, without having to redefine it in an Ext.Ajax success callback?
For a store, you can
Ext.define('myNewCustomStore',{
constructor:function(config){
this.callParent(arguments);
this.on('load',function(store,records,e){myCustomMetaDataHandler()});
}
});
And then instead of using
Ext.create('Ext.data.Store' or Ext.define('myStore',{extends:Ext.data.Store
You create / extend myNewCustomStore
And Json without models?
Ext.Ajax.request({
url: 'page.php',
params: {
id: 1
},
success: function(response){
var text = response.responseText;
var json = Ext.JSON.decode(text);
//now do stuff
}
});
I have spent days working on this and really feel dumb. I have been working on demos and samples that never work when I try it locally with my own url. I have a web service that returns results back in json and am just basically trying to call it using dojo and for now just view the results. I took the search google example and just substituted the url and parameters. Now perhaps I still do not understand the basics so:
- io.script.get vs xhrGet
if using cross domain urls it is better to use io.script.get? correct?
now what is the callbackparam? is this the function that is being called in the webservice?
My webservice url is as follows:
http://xxx.xxx.x.xxx/WcfServices/WcfInstance/Service1.svc/RetrievData?query=Word
when I use the following code I get nothing displayed.
function searchGoogle() {
// Look up the node we'll stick the text under.
var targetNode = dojo.byId("rules");
// The parameters to pass to xhrGet, the url, how to handle it, and the callbacks.
var jsonpArgs = {
url: "http://xxx.xxx.x.xxx/WcfServices/WcfInstance/Service1.svc/RetrieveData?",
callbackParamName: "callback",
content: {
query:"dojowords"
},
load: function (data) {
// Set the data from the search into the viewbox in nicely formatted JSON
targetNode.innerHTML = "<pre>" + dojo.toJson(data, true) + "</pre>";
},
error: function (error) {
targetNode.innerHTML = "An unexpected error occurred: " + error;
}
};
dojo.io.script.get(jsonpArgs);
}
dojo.ready(searchGoogle);
Here is what the webservice results look like:
"{\"rules\":[{\"value\":\"AllState\"},
{\"value\":\"Cidade de Goa beach\"},{\"value\":\"Euro 2012\"},
{\"value\":\"Euro2012\"},{\"value\":\"European&Championship\"},
{\"value\":\"Holiday Inn Resort\"},
{\"value\":\"Holiday Inn Resort goa\"},
{\"value\":\"Hotel Goa\"},{\"value\":\"Hyatt Goa\"},{\"value\":\"I buy car\"},...
If I get this part correct then at least I know I have data which I can then bind to a datagrid or chart.
dojo.io.script.get is for all cross domain requests.
xhrGet is for same domain requests.
dojo.io.script.get uses a hack which expects jsonp or json padding as a result. This wraps the response of the web service call inside a self executing function. The function name is the callback name. This has to be wired before the call so it knows what already defined function to call when a response comes back.
All of the arguments are well documented http://dojotoolkit.org/reference-guide/1.7/dojo/io/script.html
My guess as to why your service isn't working is because you wrote the web service and it does not handle jsonp. It is not wrapping its response inside the callbackparamname.
your results should look something like
callback({json});
where callback is whatever you set up in callbackParamName
you can also remove the ? from your url, that should be handled for you.