Error: Cannot create a pointer to an unsaved ParseObject - parse-platform

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.

Related

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

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

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

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

SlickGrid filter not working

I am fairly new to SlickGrid. I am trying to make SlickGrid filter work but no luck. I am following the example (http://mleibman.github.io/SlickGrid/examples/example4-model.html).
Below is my source code.
$(document).ready(function() {
var tName;
$('#submit').click(function(e) {
tName = $('#source option:selected').text();// name1
tName = tName.trim();
$.ajax({
url : 'someUrl',
type : 'GET',
cache : false,
success : function(d) {
var grid;
var searchString = "";
var data = [];
var columns = new Array();
var cols = d[0].columns;
var pkColNames = d[0].pkColNames;
for (var j=0; j< cols.length; j++) {
var key = {id: cols[j].colName, name: cols[j].colName, field: cols[j].colName, width: 200, sortable:true, editor: Slick.Editors.LongText};
columns[j] = key;
}
var options = {
editable: true,
enableAddRow: false,
enableCellNavigation: true,
asyncEditorLoading: false,
enableColumnReorder:true,
multiColumnSort: false,
autoEdit: false,
autoHeight: false
};
function myFilter(item, args) {
return true;// Let us return true all time ?
}
for (var i = 0; i < d.length; i++) {
var tempData = (data[i] = {});
var title = null;
var val = null;
for (var q = 0; q < d[i].columns.length; q++) {
title = d[i].columns[q].colName;
val = d[i].columns[q].colValue;
tempData[title] = val;
}
}
var dataView = new Slick.Data.DataView({ inlineFilters: true });
grid = new Slick.Grid("#myGrid", dataView, columns, options);
dataView.setPagingOptions({
pageSize: 25
});
var pager = new Slick.Controls.Pager(dataView, grid, $("#myPager"));
var columnpicker = new Slick.Controls.ColumnPicker(columns, grid, options);
grid.setSelectionModel(new Slick.CellSelectionModel());
grid.onAddNewRow.subscribe(function(e, args) {
// Adding a new record is not yet decided.
});
grid.onCellChange.subscribe(function (e) {
var editedCellNo = arguments[1].cell;
var editedColName = grid.getColumns()[editedCellNo].field;
var newUpdatedValue= arguments[1].item[grid.getColumns()[editedCellNo].field];
var editedColType = "";
for (var cnt = 0; cnt < cols.length; cnt++) {
if (editedColName == cols[cnt].colName) {
editedColType = cols[cnt].colType;
break;
}
}
var pkKeyValue="";
for (var v=0; v <pkColNames.length;v++) {
for (var p=0; p<grid.getColumns().length; p++) {
if (pkColNames[v] == grid.getColumns()[p].field) {
var value = arguments[1].item[grid.getColumns()[p].field];
pkKeyValue += "{"+pkColNames[v] + '~' +getColDbType(grid.getColumns()[p].field) + ":"+value+"},";
break;
}
}
}
function getColDbType(colName) {
for (var c = 0; c < cols.length; c++) {
if (colName == cols[c].colName) {
return cols[c].colType;
}
}
}
pkKeyValue = pkKeyValue.substring(0, pkKeyValue.length-1);
$.ajax({
url: 'anotherUrl',
type:'GET',
dataType:'text',
success: function(f) {
bootbox.alert("Data updated successfully");
},
error: function() {
bootbox.alert("Error - updating data. Please ensure you are adding the data in right format.");
grid.invalidateAllRows();
grid.render();
}
});
});
grid.onClick.subscribe(function (e) {
//do-nothing
});
dataView.onRowsChanged.subscribe(function(e, args) {
grid.updateRowCount();
grid.invalidateRows(args.rows);
grid.render();
});
grid.onSort.subscribe(function(e, args) {
// args.multiColumnSort indicates whether or not this is a multi-column sort.
// If it is, args.sortCols will have an array of {sortCol:..., sortAsc:...} objects.
// If not, the sort column and direction will be in args.sortCol & args.sortAsc.
// We'll use a simple comparer function here.
var comparer = function(a, b) {
return a[args.sortCol.field] > b[args.sortCol.field];
}
// Delegate the sorting to DataView.
// This will fire the change events and update the grid.
dataView.sort(comparer, args.sortAsc);
});
// wire up the search textbox to apply the filter to the model
$("#txtSearch").keyup(function (e) {
console.log('Called...txtSearch');
Slick.GlobalEditorLock.cancelCurrentEdit();
// clear on Esc
if (e.which == 27) {
this.value = "";
}
searchString = this.value;
updateFilter();
});
function updateFilter() {
console.log("updateFilter");
dataView.setFilterArgs({
searchString: searchString
});
dataView.refresh();
}
dataView.beginUpdate();
dataView.setItems(data, pkColNames);
dataView.setFilterArgs({
searchString: searchString
});
dataView.setFilter(myFilter);
dataView.endUpdate();
},
error : function() {
bootbox.alert("Invalid user");
}
});
});
});
Your function myFilter() is always returning true so of course it will never work. The example that you looked at, was to filter something specific. I would recommend that you look at the following example to have a generic filter. From the example, simply type the text you are looking on a chosen column and look at the result... see example below (from SlickGrid examples).Using fixed header row for quick filters
In case you want a more in depth conditional filters ( > 10, <> 10, etc...), please take a look at my previous answer on how to make this kind of filtering possible, see my previous answer below:SlickGrid column type
Hope that helps you out

Resources