Parse Cloud Code getting Error Failed with: TypeError: Object 0 has no method 'set' - parse-platform

Im using Cloud Code for my Android App.
After saving a Value to a Parse Class I want to Update a field (credits) from my Users.
var query = new Parse.Query(Parse.User);
query.equalTo("householdOf", request.params.household);
query.find({
success: function(roomMates) {
for (var roomMate in roomMates)
{
if(roomMate != currentUser)
{
roomMate.set(
{
credit: 3
},
{
error: function(gameTurnAgain, error)
{
console.log("set failed " +error.code + error.message);
response.error("error");
}
});
}
}
this is my Cloud Code. I get the Error (TypeError: Object 0 has no method 'set') by roomMate.set
The roomMates must be Parse.User or am I wrong?

I am not professional in JS, but I am also playing with parse Cloude Code. So I suppose that you enumerate roomMates incorrectly.
You should enumerate array and get object like:
for (var i=0; i<roomMates.length; i++) {
roomMate = roomMates[i];
}
The key in enumerator works in key-value dictionaries to enumerate keys.
var dictionary = {key1 : "Hi", key2: "Bye"};
for (var key in dictionary) {
obj = dictionary[key];
}

Related

The URL that should display a Google Sheet data in JSON format shows internal error

I want to convert the data of a Google Sheet into JSON format so that I can use it on my website. However, I get a 500 error whenever the website tries to fetch the JSON file.
I have already tried different methods to convert my sheet into JSON that are available on the internet
$url = 'https://spreadsheets.google.com/feeds/list/1dpmzzKNR8hRILX6qMD0KTruxxXYT3UAXR0EcX0zS0dE/1/public/full?alt=json';
$file= file_get_contents($url);
$json = json_decode($file);
$rows = $json->{'feed'}->{'entry'};
return $rows;
I had the same problem; I was able to work around the problem by parsing the html from the pubhtml page directly to output a similar JSON format:
Instead of using the Google Sheet ID, use the link for "Publish to Webpage".
There are some rows that I skip since some are for frozen rows, but you should be able to modify the code to your needs.
function importGoogleSheets(publishedUrl, sheetId, onSuccess, onError) {
var headers = [];
var rows;
$.ajax({
url: publishedUrl+'?gid='+sheetId+'&single=true',
success: function(data) {
data = $.parseHTML(data)[5];
htmldata = data;
rows = data.getElementsByTagName('tr');
for (var i = 0; i < rows[1].cells.length; i++) {
headers[i] = 'gsx$' + rows[1].cells[i].textContent.toLowerCase().replace(/[^0-9a-z]*/g, '');
}
for (var i = 3; i < rows.length; i++) {
temp = {};
for (var h = 1; h < headers.length; h++) {
temp[headers[h]] = {'$t': rows[i].cells[h].textContent};
}
all_data[i - 3] = temp;
}
onSuccess(all_data);
},
error: function(data) {
onError(data);
}
});
}
One note though is that it includes any empty rows unlike the feed, so you may want to filter the ouptut based on some column.

accessing addressused in activityparty when using javascript

When I create a new Activityparty with:
// Create an activity party for the email TO
Entity[] activityPartyTo = new Entity[1];
activityPartyTo[0] = new Entity("activityparty");
activityPartyTo[0]["addressused"] = "john#email.com"
activityPartyTo[0]["partyid"] = new EntityReference("contact", to.Get(executionContext).Id);
email["to"] = activityPartyTo;
I'm referencing a specific contact, but I don't want to use the default emailaddress1 or emailaddress2 in contact so i set "addressused".
The question is where can I access it in javascript? This code gives me all activityparties but the only attribute I see is name and type
var party = Xrm.Page.getAttribute("to");
var members = party.getValue();
for (var i = 0; i < members.length; i++) {
// Contact
if (members[i].type == 2) {
alert("Contact Id: " + members[i].id + " Name: " + members[i].name + " addressused: " + members[i].addressused);
}
}
but addressused is undefined, can someone tell me where addressused is stored?
Once you get the Activity Party id from the lookup field you will need to execute the following request to the WebAPI to get the addressused(the retrieve method can't be used with this entity so that's why I'm using a filter):
GET /api/data/v9.0/activityparties?$select=addressused&$filter=activitypartyid eq YOURID
If you're using v9 you can use the following code:
Xrm.WebApi.retrieveMultipleRecords("activityparty", "?$select=addressused&$filter=activitypartyid eq 04c31532-4ae5-e511-80fe-00155d09ab01").then(
function success(result) {
for (var i = 0; i < result.entities.length; i++) {
console.log(result.entities[i].addressused);
}
},
function (error) {
console.log(error.message);
}
);

Get courses.list without archived classes

Using a HTTP GET request, how would you only get the classes that are active. Could you add a parameter to the Google API URL that only returns a list of active classes? Or do you have to search through the returned array and delete any classes are archived using a for loop?
var classroom = new XMLHttpRequest();
var accessToken = localStorage.getItem('accessToken');
classroom.open('GET',
'https://classroom.googleapis.com/v1/courses');
classroom.setRequestHeader('Authorization',
'Bearer ' + accessToken);
classroom.send();
classroom.onload = function () {
if (classroom.readyState === classroom.DONE) {
if (classroom.status === 200) {
var response = JSON.parse(classroom.response);
vm.classes = response.courses;
console.log(response);
for (var i = 0; i < response.courses.length; i++){
var courses = response.courses[i];
console.log(courses.name);
}
} else {
console.log("Error Unknown");
}
}
};
Any help would be much appreciated.
Thanks!
There's no filter option yet like with User objects. (That's documented for at least as far as I can tell). So yes you'll have to pull all of the courses and then just filter out the archived courses. https://developers.google.com/classroom/reference/rest/v1/courses there's a CourseState section that lists the 5 possible states a course can be in. [COURSE_STATE_UNSPECIFIED, ACTIVE, ARCHIVED, PROVISIONED, DECLINED]
Reading through the docs, courses.list returns a list of courses that the requesting user is permitted to view. It does not state a direct way of retrieving active classes only. You may have to resort to your said implementation.
Try this:
function get_courses(student) {
var optionalArgs = {
studentId: student
};
var response = Classroom.Courses.list(optionalArgs);
var courses = response.courses;
var active_courses = [];
if (courses && courses.length > 0) {
for (i = 0; i < courses.length; i++) {
var course = courses[i];
if(course.courseState == "ACTIVE"){
active_courses.push(course);
Logger.log('%s (%s)', course.name, course.id);
}
}
} else {
Logger.log('No courses found.');
}
return active_courses;
}

How to pass Parameters in Ruby for Google App Script

I have the following script in Google Apps:
function createSpreadsheet(environment, timestamp) {
Logger.log(environment);
var folders = DriveApp.getFoldersByName(environment);
while (folders.hasNext()) {
var folder = folders.next();
}
var testName = timestamp + ".test_" + environment;
Logger.log(testName);
var file = {
"title": testName,
"mimeType": "application/vnd.google-apps.spreadsheet",
"parents": [
{
"id": folder.getId()
}
]
};
Drive.Files.insert(file);
var allFiles = folder.getFilesByName(testName);
var files = {};
while (allFiles.hasNext()) {
var file = allFiles.next();
return file.getId();
}
}
and from Ruby code I am performing the following call
request = Google::Apis::ScriptV1::ExecutionRequest.new
request.function = 'createSpreadsheet'
request.parameters = [environment.to_s ,timestamp.to_s ]
But it is not working and I get error during the execution of the script:
Script error message: Cannot call method "getId" of undefined.
What I am doing wrong ? that parameters are a simple strings
Thanks a lot
It was my fault I forgot publishing my last change in the script

Parse Cloud Code - How to query the User Class

I'm trying to query the Parse User Class but I'm not getting any results. The User class has a column labeled "phone", and I'm passing an array of dictionaries where each dictionary has a key "phone_numbers" that corresponds to an array of phone numbers. I'm trying to determine if a User in my table has one of those phone numbers. I'm not getting any errors running the code, but there does exist a user in my table with a matching phone number. What am I doing wrong?
Parse.Cloud.define("hasApp", function(request, response) {
var dict = request.params.contacts;
var num = 0;
var found = 0;
var error = 0;
var phoneNumbers = "";
for (var i = 0; i < dict.length; i++){
var result = dict[i].phone_numbers;
num += result.length;
for (var j = 0; j < result.length; j++){
phoneNumbers += result[j] + ", ";
var query = new Parse.Query(Parse.User);
query.equalTo("phone", result[j]);
query.find({
success: function(results) {
found = 1;
},
error: function() {
error = 1;
}
});
}
}
response.success("hasApp " + dict.length + " numbers " + num + " found " + found + " error " + error + " phoneNumbers " + phoneNumbers);
});
My response from calling this is
hasApp 337 numbers 352 found 0 error 0 phoneNumbers "list of phone numbers"
where some of those phone numbers appear in my User class. As far as I can tell I'm not getting any errors but I'm also not successfully querying the User table
UPDATE
After moving
response.success("hasApp " + dict.length + " numbers " + num + " found " + found + " error " + error + " phoneNumbers " + phoneNumbers);
to the body of the success block, I get the following error because I'm only allowed to call response.success once per cloud function.
Error Domain=Parse Code=141 "The operation couldn’t be completed. (Parse error 141.)"
UserInfo=0x14d035e0 {code=141, error=Error: Can't call success/error multiple times
at Object.success (<anonymous>:99:13)
at query.find.success (main.js:44:12)
at Parse.js:2:5786
at r (Parse.js:2:4981)
at Parse.js:2:4531
at Array.forEach (native)
at Object.w.each.w.forEach [as _arrayEach] (Parse.js:1:666)
at n.extend.resolve (Parse.js:2:4482)
at r (Parse.js:2:5117)
at Parse.js:2:4531}
Does this mean that I'm only able to verify one phone number at a time? So I can't pass an array of phone numbers and get the PFUser objects corresponding to those phone numbers (if they exist)?
I understand that my internal query to Parse.User is happening synchronously with my "hasApp" call, so is there a way to query Parse.User asynchronously? That way I can respond back to the client after checking all the phone numbers?
You can use Parse.Promise to solve logic where you need to iterate through O(n) number of database queries in one asynchronous Cloud Code definition:
var _ = require("underscore"),
isEmpty = function (o) { // standard function to check for empty objects
if (o == null) return true;
if (o.length > 0) return false;
if (o.length === 0) return true;
for (var p in o) {
if (hasOwnProperty.call(o, p)) return false;
}
return true;
};
Parse.Cloud.define("hasApp", function (request, response) {
var dict = request.params.contacts,
users = [];
var promise = Parse.Promise.as();
_.each(dict, function (obj) {
_.each(obj.phone_numbers, function (num) {
promise = promise.then(function () {
var promiseQuery = new Parse.Query(Parse.User);
promiseQuery.equalTo("phone", parseInt(num));
return promiseQuery.find({
success: function (result) {
if (isEmpty(result)) // don't save empty results e.g., "[]"
return;
users.push(result); // save results to a model to prevent losing it in scope
}
});
});
});
});
return promise.then(function () {
response.success("Found user(s): " + JSON.stringify(users));
});
});
Note a few things about this block:
You can append functionality iteratively to a Parse.Promise.
You can loose scope of database results in your iteration. Use a local array model to save your query results to. Although, I presume there is a better way to achieve the same functionality without the use of a user model, someone else can quote me on that.
Pay close attention to the way Parse handles data. For example, if you are storing your phone numbers as numbers, you have to make sure you use parseInt() when querying for it.
Be aware that you must attach your response.success() function to your promise to assure it is resolved after your iterations have run. From this block, your response from Parse will look similar to an array of User objects. You can decide on the many different ways you can save the data model depending on what you need it for.
As a final note, this block doesn't account for any validation or error handling that should be accounted for otherwise.
The problem seems to be that your response.success call is happening before the query can even happen. While you have response.success calls in your query success block, they are never called because you return success before the query is executed.
Try commenting out the line:
response.success("hasApp " + dict.length + " numbers " + num + " found " + found + " error " + error + " phoneNumbers " + phoneNumbers);
This should let the code go to your query, and maybe move it into the success block of your query.
Let me know if this works.
You're now calling response.success in a loop now. You should only call response.success/response.error once per cloud function.
It would help if you can show the original code with no commented out lines (to show your original intention) and the new code with no commented out lines as two separate code samples.
Querying a Parse.User is fairly easy and well explained in the documentation, here is an example taken from it
var query = new Parse.Query(Parse.User);
query.equalTo("gender", "female"); // find all the women
query.find({
success: function(women) {
// Do stuff
}
});
For your case it will be something like this:
Parse.Cloud.define("getAllFemales", function(request, response) {
var query = new Parse.Query(Parse.User);
query.equalTo("gender", "female"); // find all the women
query.find({
success: function(women) {
// Do stuff
}
});
});
Hope it helps, as always more info on the Documentation

Resources