Where to declare response.success()/response.error() in my cloud code - parse-platform

Hi while I run this Job in Cloud code I get an error log:
Failed with: success/error was not called. Define functions working good, but in Job logs I have this error log. Please assist me to solve the issue
Parse.Cloud.job("JobSchedule", function (request, response) {
var Group = Parse.Object.extend("Group");
var query = new Parse.Query(Group);
query.equalTo("JobScheduled", true);
query.find({
success: function (results) {
for (var i = 0; i < results.length; ++i) {
var created = new Date(results[i].createdAt);
var current = new Date();
var timeDiff = Math.abs(current.getTime() - created.getTime());
var horsDiff = timeDiff / (60 * 60 * 1000);
if (horsDiff >= parseInt(results[i].get("JobHours"))) {
results[i].set("JobScheduled", false);
results[i].set("GroupType", "Private");
results[i].set("JobHours", 0);
results[i].save();
var GroupMembers = Parse.Object.extend("GroupMembers");
var query1 = new Parse.Query(GroupMembers);
query1.equalTo("GroupId", results[i].id);
query1.find({
success: function (grpresults) {
for (var j = 0; j < grpresults.length; ++j) {
grpresults[j].set("GroupType", "Private");
grpresults[j].save();
}
},
error: function (error) {
response.error(error);
}
});
}
}
},
error: function (error) {
response.error(error);
}
});
});

In each of your success scenarios, you need to call response.success(), where between the parenthesis you can return a status message, such as
response.success('Hello world did work');
In your case, this would probably go here:
Parse.Cloud.job("JobSchedule", function (request, response) {
var Group = Parse.Object.extend("Group");
var query = new Parse.Query(Group);
query.equalTo("JobScheduled", true);
query.find({
success: function (results) {
for (var i = 0; i < results.length; ++i) {
var created = new Date(results[i].createdAt);
var current = new Date();
var timeDiff = Math.abs(current.getTime() - created.getTime());
var horsDiff = timeDiff / (60 * 60 * 1000);
if (horsDiff >= parseInt(results[i].get("JobHours"))) {
results[i].set("JobScheduled", false);
results[i].set("GroupType", "Private");
results[i].set("JobHours", 0);
results[i].save();
var GroupMembers = Parse.Object.extend("GroupMembers");
var query1 = new Parse.Query(GroupMembers);
query1.equalTo("GroupId", results[i].id);
query1.find({
success: function (grpresults) {
for (var j = 0; j < grpresults.length; ++j) {
grpresults[j].set("GroupType", "Private");
grpresults[j].save();
}
// HERE IS THE NEW CODE
response.success("Saved objects properly");
},
error: function (error) {
response.error(error);
}
});
}
}
error: function (error) {
response.error(error);
}
});
});

Related

Error: Cannot create a pointer to an unsaved ParseObject

I am getting below error after updating to parse's latest release.
Result: Error: Cannot create a pointer to an unsaved ParseObject
at n.value (Parse.js:12:4222)
at n (Parse.js:14:607)
at Parse.js:14:374
at Array.map (native)
at n (Parse.js:14:351)
at Object.r.default (Parse.js:14:1071)
at Object.b._encode (Parse.js:11:15607)
at Object.success (<anonymous>:156:42)
at e.rQuery.find.success (main.js:279:22)
at e.<anonymous> (Parse.js:12:27827)
for below code
rQuery.equalTo("rNumber", r2Number);
rQuery.descending("rDateTime");
rQuery.find({
success: function(results) {
results = editListForSectionHeader(results);
response.success(results);
},
error: function(error) {
// on error, log it
console.log(error.message);
response.success([]);
}
function editListForSectionHeader(results){
var previousDate = '';
var formatedResults = [];
for (var i = 0; i < results.length; i++) {
var object = results[i];
if(previousDate != object.get('rDate')){
var headerRow = new R();
headerRow.set("rDate", object.get('rDate'));
headerRow.set("rowType", "HEADER_ROW");
formatedResults.push(headerRow);
object.set("rowType", "DATA_ROW");
formatedResults.push(object);
previousDate = object.get('rDate');
headerRow.dirty = function() { return false; };
object.dirty = function() { return false; };
}else{
object.set("rowType", "DATA_ROW");
object.dirty = function() { return false; };
formatedResults.push(object);
}
}
return formatedResults;
}
Basically I am getting some data with query, formatting the result array, setting dirty properties to false and returning. It use to work but it stopped with the new version.

Cloud Code, complex query with adding a key-value pair before response

I want to get a batch of User objects using Cloud Code. And before collection of objects will send to client they have to take a unique number.
Now it's looking like this
Parse.Cloud.define("getUsers", function(request, response)
{
var query = new Parse.Query(Parse.User);
var mode = parseInt(request.params.mode);
var username = request.params.username;
var skip = parseInt(request.params.skip);
var limit = parseInt(request.params.limit);
if(mode==1)
{
query.notEqualTo("fbLogged",true)
.descending("score")
.notEqualTo("username",username)
.skip(skip)
.limit(limit);
query.find({
success: function(objects)
{
var i = 0;
objects.forEach(function(item)
{
item["rank"]=skip+i; //setting a unique number (position based on score)
});
response.success(objects);
},
error: function(error)
{
response.error(error);
}
});
}
});
And how I use it on client side...
void Start () {
IDictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("username", "477698883");
dict.Add("skip", "300");
dict.Add("limit", "50");
dict.Add("mode", "1");
ParseCloud.CallFunctionAsync<IEnumerable<object>>("getUsers", dict).ContinueWith(t =>
{
if(t.IsCanceled || t.IsFaulted)
{
foreach (var e in t.Exception.InnerExceptions)
Debug.LogError(e.Message);
}
else
{
var r = t.Result;
List<ParseUser> users = new List<ParseUser>();
foreach(var o in r)
{
try {
ParseObject pu = (ParseObject)o;
foreach (var key in pu.Keys)
Debug.Log(key + " = " + pu[key]);
}
catch(Exception e)
{
Debug.LogError(e.Message);
}
break;
}
}
});
}
As you see I just display first of received objects.
And it gives me this data.
But where is the "rank" field?
I just found solution. Each ParseObject which will send to Client by response.success() have to be saved on Parse before sent.
Now my code looks like this and it works
Parse.Cloud.define("getUsers", function(request, response)
{
var query = new Parse.Query(Parse.User);
var mode = parseInt(request.params.mode);
var username = request.params.username;
var skip = parseInt(request.params.skip);
var limit = parseInt(request.params.limit);
if(mode==1)
{
query.notEqualTo("fbLogged",true)
.descending("score")
.notEqualTo("username",username)
.skip(skip)
.limit(limit);
query.find({
success: function(objects)
{
for(var i = 0; i<objects.length; i++)
{
objects[i].set("rank", skip+i);
objects[i].save();
}
response.success(objects);
},
error: function(error)
{
response.error(error);
}
});
}
});

Error Message- Failed with: success/error was not called

Parse.Cloud.job("JobSchedule", function(request, response) {
var Group = Parse.Object.extend("Group");
var query = new Parse.Query(Group);
query.equalTo("JobScheduled", true);
query.find({
success: function(results) {
for (var i = 0; i < results.length; ++i) {
var created = new Date(results[i].createdAt);
var current = new Date();
var timeDiff = Math.abs(current.getTime() - created.getTime());
var horsDiff = timeDiff / (60 * 60 * 1000);
if (horsDiff >= parseInt(results[i].get("JobHours"))) {
results[i].set("JobScheduled", false);
results[i].set("GroupType", "Private");
results[i].set("JobHours", 0);
results[i].save();
var GroupMembers = Parse.Object.extend("GroupMembers");
var query1 = new Parse.Query(GroupMembers);
query1.equalTo("GroupId", results[i].id);
query1.find({
success: function(grpresults) {
for (var j = 0; j < grpresults.length; ++j) {
grpresults[j].set("GroupType", "Private");
grpresults[j].save();
}
},
error: function(error) {
response.error(error);
}
})
}
}
},
error: function(error) {
response.error(error);
}
});
});
Script is running properly(it updates the values as defined). But in parse log it shown as Failed with: success/error was not called. Please suggest me over this issue
You simply never call response.success() or response.error(), and you should always call at least one of those.
You should really be storing all of the promises returned from your queries and saves and waiting until all of them are complete and then calling success or error based on the result from those promises.

Saving a Parse object within a for loop does save all the objects

I have the following code where I am trying to save personalities of a movie. Only few personalities get created and saved.
var query = new Parse.Query(Movie);
query.find({ success: function(movies) {
console.log("movies.length " + movies.length );
for (var movieIterator = 0; movieIterator < movies.length ; movieIterator++) {
cast_array = movies[movieIterator].get("cast");
console.log(cast_array);
for (var i = 0; i < cast_array.length; i++) {
var personalityObj = new Personality();
personalityObj.set('name', cast_array[i].trim());
personalityObj.save(); // NOt all personalities get saved
}
}
response.success("Awesome");
}, error: function(error) {
response.error(error)
}});
How may I improve the code so that all the personalities get stored/saved in the DB.
Can you try this and let me know if it works.
var query = new Parse.Query(Movie);
query.find({ success: function(movies) {
console.log("movies.length " + movies.length );
var list = [];
for (var i = 0; i < movies.length ; i++) {
cast_array = movies[i].get("cast");
console.log(cast_array);
for (var j = 0; j < cast_array.length;j++) {
var personalityObj = new Personality();
personalityObj.set('name', cast_array[j].trim());
list.push(personalityObj);
}
}
Parse.Object.saveAll(list).then(function(results){
console.log("Objects were saved!");
response.success("Awesome");
},function(eerror){
console.log(eerror);
response.error(eerror);
});
}, error: function(error) {
response.error(error);
}});
The above code is using saveAll function for batch operation. Docs

Json result returned as a file in Internet Explorer?

net MVC application, in which I have multiple charts. On these charts, I have applied filters and by clicking each filter, I do an ajax call which returns the result in Json and then applies to the charts.
Now its working perfectly in Firefox and Chrome, but in Internet Explorer - Ajax call is always unsuccessful. I tried hitting the web api url directly through my browser and the issue it seems is, the result json was being returned as a file to be downloaded.
This is my ajax code :
function getIssueResolvedGraphdata(control, departCode, departName) {
$.ajax(
{
type: "GET",
url: WebApiURL + "/api/home/GetQueryIssueResolvedData?deptCode=" + departCode,
dataType: "json",
crossDomain: true,
async: true,
cache: false,
success: function (myData) {
var resolvedStartDate = myData.data.IssueResolvedStartDate;
var issueData = myData.data.IssueData;
var resolveData = myData.data.ResolvedData;
//converting issueData into integer array...
var issue = issueData.replace("[", "");
var issue1 = issue.replace("]", "");
var issue2 = issue1.split(",");
for (var i = 0; i < issue2.length; i++) { issue2[i] = parseInt(issue2[i]); }
//converting resolvedData into integer array
var resolve = resolveData.replace("[", "");
var resolve1 = resolve.replace("]", "");
var resolve2 = resolve1.split(",");
for (var j = 0; j < resolve2.length; j++) { resolve2[j] = parseInt(resolve2[j]); }
//getting max value from array...
var issueMaxVal = Math.max.apply(null, issue2);
var resolveMaxVal = Math.max.apply(null, resolve2);
//Eliminating leading zeros in issue array
var removeIndex = 0;
var myDate;
var newDate;
var arrayLength;
if (issueMaxVal != 0) {
arrayLength = issue2.length;
for (var i = 0; i < arrayLength; i++) {
if (issue2[0] == 0) {
issue2.splice(0, 1);
removeIndex = i;
} else {
break;
}
}
//Getting days count of current month
var monthStart = new Date(new Date().getFullYear(), new Date().getMonth(), 1);
var monthEnd = new Date(new Date().getFullYear(), new Date().getMonth() + 1, 1);
var monthLength = (monthEnd - monthStart) / (1000 * 60 * 60 * 24);
var monthDays = 0;
if (monthLength == 28) {
monthDays = removeIndex;
}
else if (monthLength == 30) {
monthDays = removeIndex + 1;
}
else if (monthLength == 31 || monthLength == 29) {
monthDays = removeIndex + 2;
}
//matching the resultant issue array with resolve array & setting start date
var iDate = resolvedStartDate;
var tDate = '';
for (var i = 0; i < iDate.length; i++) {
if (iDate[i] == ',') {
tDate += '/';
}
else {
tDate += iDate[i];
}
}
if (removeIndex != 0) {
resolve2.splice(0, (removeIndex + 1));
var myDate = new Date(tDate);
myDate.setDate(myDate.getDate() + monthDays);
newDate = Date.UTC(myDate.getFullYear(), (myDate.getMonth() + 1), myDate.getDate());
} else {
var myDate = new Date(tDate);
newDate = Date.UTC(myDate.getFullYear(), (myDate.getMonth() + 1), myDate.getDate());
}
} else {
alert("Empty");
}
//updating chart here...
var chart = $('#performance-cart').highcharts();
chart.series[0].update({
pointStart: newDate,
data: issue2
});
chart.series[1].update({
pointStart: newDate,
data: resolve2
});
if (issueMaxVal > resolveMaxVal) {
chart.yAxis[0].setExtremes(0, issueMaxVal);
} else {
chart.yAxis[0].setExtremes(0, resolveMaxVal);
}
},
error: function (x, e) {
alert('There seems to be some problem while fetching records!');
} });}
Code from web api controller :
[HttpGet]
[CrossDomainActionFilter]
public Response<GraphIssueResolvedWrapper> GetQueryIssueResolvedData(string deptCode)
{
Response<GraphIssueResolvedWrapper> objResponse = new Response<GraphIssueResolvedWrapper>();
GraphIssueResolvedWrapper objGraphIssueResolvedWrapper = new GraphIssueResolvedWrapper();
try
{
....code.....
objResponse.isSuccess = true;
objResponse.errorDetail = string.Empty;
objResponse.data = objGraphIssueResolvedWrapper;
}
catch (Exception ex)
{
objResponse.isSuccess = false;
objResponse.errorDetail = ex.Message.ToString();
objResponse.data = null;
}
return objResponse;
}
Reponse Class :
public class Response<T>
{
public bool isSuccess { get; set; }
public string errorDetail { get; set; }
public T data { get; set; }
}
I am stuck at this for hours now. Any help will be appreciated.
I have solved my problem by using the following code : ( I guess it needed CORS support)
function isIE() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE");
if (msie > 0)
return true;
return false;
}
Then in document.ready function of my binding script :
$(document).ready(function () {
if (isIE())
$.support.cors = true;
});
Note : it still download Json stream as a file but now my AJAX call is successful upon each hit.
You've missed contentType: 'text/html' which is pretty important for IE7-8:
$.ajax(
{
type: "GET",
url: WebApiURL + "/api/home/GetQueryIssueResolvedData?deptCode=" + departCode,
dataType: "json",
contentType: 'text/html'
crossDomain: true,
async: true,
cache: false,
success: function (myData) {
var result = JSON.parse(myData);
///...code...
},
error: function (x, e) {
alert('There seems to be some problem while fetching records!');
}
}
);
To make it works in IE7-8 you also need to be sure that you've writing Conrent-Type Header into your response on server side. Add this line right before return statement;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html; charset=iso-8859-1");
And in code probably you will need to parse result in success method by using JSON.parse(myData);

Resources