Parse server error: Uncaught internal server error. {“stack”:“Error”} - parse-platform

I have user import query:
const userObj = Parse.Object.extend("User");
var addingList = [];
for (var i = 0; i < downloadedCustomers.length; i++) {
var user = new userObj();
user.set("username", downloadedCustomers[i].cardcode);
user.set("password", downloadedCustomers[i].password);
user.set('name', downloadedCustomers[i].cardname);
addingList.push(user)
user.save( { useMasterKey: true }).then((success)=>{
console.log(success)
}).catch((error)=>{
console.log(error)
})
}
when i use this code on array, sometimes gives
error: Uncaught internal server error. {“stack”:“Error”} on some keys, but sometimes successfully saves all keys.
if i use :
Parse.Object.saveAll(addingList, { useMasterKey: true })
somekeys got saved, still some not saved.
How can i import all keys successful everytime?
PS: same situation on user.signUp()

I fixed it dividing object requests into 10 pieces of chunks.
Seems parse user object saving needs time process and resolve.
for (h = 0, k = addingList.length; h < k; h += chunk2) {
temparray = addingList.slice(h, h + chunk2);
await Parse.Object.saveAll(temparray,{useMasterKey:true}).then((success) => {
console.log(h + chunk2 + ’ customers were added from total ’ + k);
return h + chunk2 + ’ customers were added from total ’ + k
}).catch((error) => {
console.log('Some customers were failed to import in chunk : ’ + h + ‘. Error:’ + error);
console.log(error)
return 'Some customers were failed to import in chunk : ’ + h + ‘. Error:’ + error
});
}
Chunk size should be below 20, because it's Default object array limit in saveAll() function.

Related

Discord.js Breaking down Ban Command for Command Handler issues

I have a rather large index.js so iv been busy stripping it out into individual command files, i have successfully exported all my code into separate commands, all but ban. So far the ban code works as intended, but if a 18 digit user ID is entered, and they have left the server it should check and log it in a .json file but currently its not getting past if (isNaN(args[1])) it just plain wont accept anything, number and or letters all result in "You need to enter a vlaid #Member or UserID #" This is very frustrating as it took me hours to get working within my index.js
run: async (bot, message, args) => {
if (!message.member.hasPermission(["BAN_MEMBERS", "ADMINISTRATOR"])) return message.channel.send("You do not have permission to perform this command!")
const user1 = message.mentions.users.first();
var member = message.mentions.members.first()
if (member) {
const member = message.mentions.members.first()
let reason = args.slice(2).join(' '); // arguments should already be defined
var user = message.mentions.users.first();
member.ban({ reason: `${args.slice(2).join(' ')}` }).then(() => {
let uEmbed = new RichEmbed()
.setTitle('**' + `Sucessfully Banned ${user1.tag}!` + '**')
.setThumbnail('https://i.gyazo.com/8988806671312f358509cf0fd69341006.jpg')
.setImage('https://media3.giphy.com/media/H99r2HtnYs492/giphy.gif?cid=ecf05e47db8ad81dd0dbb6b132bb551add0955f9b92ba021&rid=giphy.gif')
.setColor(0x320b52)
.setTimestamp()
.setFooter('Requested by ' + message.author.tag, 'https://i.gyazo.com/8988806671312f358509cf0fd69341006.jpg')
message.channel.send(uEmbed);
}).catch(err => {
message.channel.send('I was unable to kick the member');
console.log(err);
});
} else {
let user = message.mentions.users.first(),
userID = user ? user.id : args[1]
if (isNaN(args[1])) return message.channel.send("You need to enter a vlaid #Member or UserID #");
if (args[1].length <= 17 || args[1].length >= 19) return message.channel.send("UserID # must be 18 Digits");
if (userID) {
let bannedIDs = require('./bannedIDs.json').ids || []
if (!bannedIDs.includes(userID)) bannedIDs.push(userID)
fs.writeFileSync('./bannedIDs.json', JSON.stringify({ ids: bannedIDs }))
let reason = args.slice(2).join(' ');
let uEmbed = new RichEmbed()
.setTitle('**' + `UserID #${args[1]}\n Will be Banned on Return!` + '**')
.setThumbnail('https://i.gyazo.com/8988806671312f358509cf0fd69341006.jpg')
.setImage('https://i.imgur.com/6Sh8csf.gif')
.setColor(0x320b52)
.setTimestamp()
.setFooter('Requested by ' + message.author.tag, 'https://i.gyazo.com/8988806671312f358509cf0fd69341006.jpg')
message.channel.send(uEmbed);
} else {
message.channel.send('Error')
}
}
}
}
Firstly, if (args[1].length <= 17 || args[1].length >= 19 can be reduced to if(args[1].length !== 18), I saw your other post and it suggests you got passed this bug, is this correct?

For loop in promise function

I have below functions that I am trying to use an async function to check if an item Id was already added into a grid. But, I am stuck at the for loop "processFindCode" function, it always returns false. How to make the checking routine work and continue to addItem function?
My objective,
1. a loop up event pass in selected array values
2. get needed info array via web api
3. process each of array item
4. validate if the item.Id_item_code already exists in detail grid, if not add a new item into the grid
sorry for the lengthy code, I am considered new to js. please also advise the best way to achieve my objective.
Thank in advance
var theList = this.value;
if (theList == "") {
return true;
}
// Set up aysnc promise function
async function processAPIResult() {
let result;
let promises = []; //setup a promises aray
// Loop thru Lookup selections
// results store in the promises aray
theList.split(',').forEach(function (kId, k) {
promises.push(make_api_call(kId));
})
result = await Promise.all(promises); // async await
return result;
}
// Call API Function
function make_api_call(id) {
return ($.get(ew.API_URL + "GetQuotationDetail/" + encodeURIComponent(id)));
}
function delay() {
return new Promise(resolve => setTimeout(resolve, 300));
}
async function addItem(kcode) {
var ridx = $("#key_count_fs_invoicedtlgrid")[0].value; // get actual table row
// Get serices information from API
var tQty = 1;
if (ridx == 1 && $("#x1_Id_item_code")[0].value == "") {
$("#x" + ridx + "_Id_item_code").value(kcode);
$("#x" + ridx + "_qty").value(tQty);
$("#x" + ridx + "_Id_item_code").select();
$("#x" + ridx + "_Id_item_code").change();
//$("#x" + ridx + "_Id_quotattoindetl").value(Id_quotationDetail); // store quotation detail Id
} else {
// 2nd row onward
// when it is available but it it is not empty, create a new row
if (typeof $("#x" + ridx + "_Id_item_code") === 'undefined' || $("#x" + ridx + "_Id_item_code")[0] != "") {
ew.addGridRow('#tbl_s_invoicedtlgrid');
}
ridx = $("#key_count_fs_invoicedtlgrid")[0].value;
var c_part_code = $("#x" + ridx + "_Id_item_code")[0];
var c_qty = $("#x" + ridx + "_qty")[0];
c_part_code.value = kcode;
c_qty.value = fmtDecimal(tQty, 'qty');
$("#x" + ridx + "_Id_item_code").select();
$("#x" + ridx + "_Id_item_code").change();
//$("#x" + ridx + "_Id_quotattoindetl").value(Id_quotationDetail); // store quotation detail Id
// trigger onChange to updateAmount() function;
$("#x" + ridx + "_qty").change();
}
}
async function processFindCode(code) {
found = false;
var rCnt = $("#key_count_fs_invoicedtlgrid")[0].value;
for (j = 1; j < rCnt + 1; j++) {
// loop thru row and col
if ($("#x" + j + "_item_code").val() != null) {
if ($("#x" + j + "_item_code").val() == kcode) {
if ($("#x" + j + "_item_code")[0].style.display != "none") { // visible row only. Deleted row's display is set to hidden.
found = true;
}
break; // exit loop column
}
}
if (found) {
break; // exit loop row
}
} // end for loop rCnt
isFound = found;
return isFound;
}
async function processItemCode(code) {
// notice that we can await a function
// that returns a promise
let isFound = await processFindCode(code);
await delay();
if (!isFound) {
await addItem(code);
}
console.log('Done! ' + code);
//await delay();
//console.log(item.Id_item_code);
}
async function processAPIitem(item) {
for (const itm of item) {
await processItemCode(itm.Id_item_code);
}
//console.log('Done! '+ apiitem.Id_item_code);
}
// main async task to get results
//-------------------------------
async function doTask() {
//get result form API function
let result = await processAPIResult();
//process each API array
for (const item of result) {
await processAPIitem([item]);
}
}
doTask();
Simple answer: $item_code.hide() hides; it isn't a test. Use $item_code.is(':visible') instead.
function processFindCode(code) {
var found = false;
var rCnt = $('#key_count_fs_invoicedtlgrid').val();
for (var j=1; j<rCnt+1; j++) {
if ($('#x' + j + '_item_code').val() != null) {
if ($('#x' + j + '_item_code').val() == code) {
if ($('#x' + j + '_item_code').is(':visible')) {
found = true;
break;
}
}
}
}
return found;
}
Longer answer: Finding the desired element with $('#x' + j + '_item_code') is inefficient especially when performed three times. You can improve matters by leveraging the power of javascript/jQuery and write something like this.
function processFindCode(code) {
var $rows = $('#tbl_s_invoicedtlgrid tbody tr'); // select all table rows in the table's tbody (assumed selector) .
return $rows.get().reduce(function(bool, row) {
return bool || $("id*='_item_code'", row).filter(':visible').filter(function() {
return this.value === code;
}).length > 0;
}, false);
}
This is still not as efficient as it could be. The "id*='_item_code'" selector is pretty nasty but at least it only applies to one row at a time, not the whole DOM.
For vastly improved efficiency, give the item_code element class="item_code" and select with $(".item_code", row). The addItem() function would benefit greatly from the same approach.

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

Need to generate random data for Highcharts series

I'm trying to generate some random data points for my Highcharts series, but I'm having issues with the data function. Here's my code (simplified from Fiddle):
series : {
name : 'Total Mentions',
type:'spline',
lineWidth:1,
data : (function() {
var arr = [];
for(var i = 0; i < 500; i++) {
var date = randomDate(new Date(2004, 0, 9), new Date());
var randNum = Math.round(Math.random()*100);
var finalDate = "Date.UTC(" + date.getFullYear() + ", " + date.getDate() + ", " + date.getMonth() + ")";
arr.push([finalDate, randNum]);
}
return arr;
})()
},
[...etc...],
The format that should be coming out should look like this:
[Date.UTC(2008, 23, 8),56],
[Date.UTC(2012, 12, 6),21],
[Date.UTC(2008, 22, 10),16],
[Date.UTC(2009, 17, 7),25],
[...etc...],
Right now, my page isn't loading the chart. The page will load infinitely, as if it's not recognizing the data.
Any thoughts?
You should push date in millisec in array, like this;
arr.push([date.getTime(), randNum]);
arr.sort(function (a,b) { if (a[0] < b[0]) return -1; if (a[0] > b[0]) return 1;
return 0; })
return arr;
I've created a fiddle at; http://jsfiddle.net/hkskoglund/cnTqS/4/
Try catching other syntax errors in the console in Chrome devtools.

Inconsistent data corruption in a store loaded through a proxy reader

We're experiencing inconsistent data corruption in a store loaded through a proxy reader.
It's browser dependant.
Works fine in Chrome and Safari on the desktop all the time.
On our two testing iPhones it intermittently breaks depending on the data the store has loaded, larger data volume seems to cause more breaks. We can't see any errors or patterns in the JSON data where it breaks.
Symptoms:
data loads, but some of the data belonging to the last few items is missing
a read listener attached to the store doesn't fire when this data loss occurs, it does fire on the desktop browser where we experience not data loss
The piece of data that always seems to be lost is the start_time.
We've been trying to debug this one for a while now and are really stumped.
Thank you for any ideas you might have as to why this is occurring.
Our regModel
Ext.regModel('Booking', {
fields: ['id', 'start', 'end', 'title', 'service', 'service_id', 'client_note', 'stylist_note', 'utc_start','day_date', 'start_time', 'end_time', "home_ph", "mobile_ph", 'work_ph', 'work_ext', 'email', 'utc_end']
});
Our store
var store = new Ext.data.JsonStore({
model : 'Booking',
sorters: 'utc_start',
autoLoad: false,
proxy: {
type: 'ajax',
url: '../includes/get_appointments.php',
extraParams: {
req_start: '1295251200',
req_end: '1295856000'
},
reader: {
type: 'json',
root: 'events'
}
},
listeners: {
load:function(store, records, success) {
bookings.setLoading(false);
// check to see length of records, start i from there
for (var i = 0; i < records.length; i++){
utc_start = records[i].get('utc_start');
utc_end = records[i].get('utc_end');
// create day of week
// y,m,d
// time
var this_start_date = new Date((utc_start * 1000));
var this_end_date = new Date((utc_end * 1000));
var day_of_week = days_of_week[this_start_date.getDay()];
var date_of_month = this_start_date.getDate();
var month_of_year = month_names[this_start_date.getMonth()];
var full_year = this_start_date.getFullYear();
var start_military_hours = this_start_date.getHours();
var this_start_minutes = this_start_date.getMinutes();
var end_military_hours = this_end_date.getHours();
var this_end_minutes = this_end_date.getMinutes();
if(this_start_minutes == "0")
{
this_start_minutes = "00";
}
if(parseInt(start_military_hours) < 12)
{
var start_time = start_military_hours + ":" + this_start_minutes + " AM";
}
else if(parseInt(start_military_hours) == 12)
{
var start_time = start_military_hours + ":" + this_start_minutes + " PM";
}
else
{
var start_time = (parseInt(start_military_hours) - 12) + ":" + this_start_minutes + " PM";
}
if(this_end_minutes == "0")
{
this_end_minutes = "00";
}
if(parseInt(end_military_hours) < 12)
{
var end_time = end_military_hours + ":" + this_end_minutes + " AM";
}
else if(parseInt(end_military_hours) == 12)
{
var end_time = end_military_hours + ":" + this_end_minutes + " PM";
}
else
{
var end_time = (parseInt(end_military_hours) - 12) + ":" + this_end_minutes + " PM";
}
var day_date = day_of_week + ", " + full_year + " " + month_of_year + " " + date_of_month;
if(records[i].get('service_id') == 0)
{
records[i].set('title', 'Booked off');
records[i].set('service', '');
}
records[i].set('day_date', day_date);
records[i].set('start_time', start_time);
records[i].set('end_time', end_time);
}
if(store.proxy.reader.rawData.next_page_num == undefined)
{
store.start = store.proxy.reader.rawData.prev_page_num;
}
else
{
store.currentPage = store.proxy.reader.rawData.next_page_num;
}
}, read:function(store,records,success){
Ext.Msg.alert('data read');
}
},
getGroupString : function(record) {
return record.get('day_date'); // optional char from array removed
}
});
Our JSON
{"events":[{"id":"3739","start":"2011-01-18T10:00:00-08:00","end":"2011-01-18T11:45:00-08:00","title":"Jen Cannor","service":"Haircut & Highlights","service_id":"67","client_note":"","stylist_note":"Looking forward to seeing Jen when she comes in next.","utc_start":"1295373600","email":"jen.c#cannorfarms.net","home_ph":"232-433-2222","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295379900"},{"id":"3740","start":"2011-01-18T12:00:00-08:00","end":"2011-01-18T13:30:00-08:00","title":"Michelle Steves","service":"Root Colour","service_id":"69","client_note":"","stylist_note":"","utc_start":"1295380800","email":"michelle5b64#telus.net","home_ph":"604-555-5555","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295386200"},{"id":"3741","start":"2011-01-18T13:30:00-08:00","end":"2011-01-18T14:00:00-08:00","title":"Amanda Brenner","service":"Wash & blow dry","service_id":"70","client_note":"","stylist_note":"","utc_start":"1295386200","email":"amandab#coastfitness.com","home_ph":"555-235-2366","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295388000"},{"id":"3742","start":"2011-01-18T14:00:00-08:00","end":"2011-01-18T15:45:00-08:00","title":"Janice Potters","service":"Haircut & Colour","service_id":"66","client_note":"","stylist_note":"","utc_start":"1295388000","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295394300"},{"id":"3743","start":"2011-01-18T15:45:00-08:00","end":"2011-01-18T16:45:00-08:00","title":"Angus Middleton","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1295394300","email":"angusman#hotmaile.com","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295397900"},{"id":"3025","start":"2011-01-19T08:00:00-08:00","end":"2011-01-19T09:45:00-08:00","title":"Jen Cannor","service":"Haircut & Highlights","service_id":"67","client_note":"","stylist_note":"","utc_start":"1295452800","email":"jen.c#cannorfarms.net","home_ph":"232-433-2222","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295459100"},{"id":"3026","start":"2011-01-19T10:00:00-08:00","end":"2011-01-19T11:45:00-08:00","title":"Karen Walker","service":"Haircut & Colour","service_id":"66","client_note":"","stylist_note":"","utc_start":"1295460000","email":"karenwalker#officesurplusdirect.net","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295466300"},{"id":"3027","start":"2011-01-19T11:45:00-08:00","end":"2011-01-19T12:45:00-08:00","title":"Amanda Brenner","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1295466300","email":"amandab#coastfitness.com","home_ph":"555-235-2366","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295469900"},{"id":"3028","start":"2011-01-19T13:00:00-08:00","end":"2011-01-19T14:30:00-08:00","title":"Mary Thacker","service":"Root Colour","service_id":"69","client_note":"","stylist_note":"","utc_start":"1295470800","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295476200"},{"id":"3029","start":"2011-01-19T14:30:00-08:00","end":"2011-01-19T15:00:00-08:00","title":"Malcolm Anderson","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1295476200","email":"malcolm#testserveraddy.com","home_ph":"240-444-4444","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1295478000"},{"id":"4856","start":"2011-03-09T09:00:00-08:00","end":"2011-03-09T10:00:00-08:00","title":"Simon Chalk","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299690000","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299693600"},{"id":"4858","start":"2011-03-09T10:00:00-08:00","end":"2011-03-09T10:15:00-08:00","title":"Brian Lytton","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299693600","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299694500"},{"id":"4859","start":"2011-03-09T10:15:00-08:00","end":"2011-03-09T10:30:00-08:00","title":"Brad Wicker","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299694500","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299695400"},{"id":"4860","start":"2011-03-09T10:30:00-08:00","end":"2011-03-09T10:45:00-08:00","title":"Brad Wicker","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299695400","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299696300"},{"id":"4861","start":"2011-03-09T10:45:00-08:00","end":"2011-03-09T11:00:00-08:00","title":"Brian Lytton","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299696300","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299697200"},{"id":"4862","start":"2011-03-09T11:00:00-08:00","end":"2011-03-09T11:15:00-08:00","title":"Brian Lytton","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299697200","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299698100"},{"id":"4863","start":"2011-03-09T11:15:00-08:00","end":"2011-03-09T11:30:00-08:00","title":"Simon Chalk","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299698100","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299699000"},{"id":"4864","start":"2011-03-09T11:30:00-08:00","end":"2011-03-09T11:45:00-08:00","title":"Chester Welling","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299699000","email":"chester#eastern.pharma.net","home_ph":"604-555-5555","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299699900"},{"id":"4865","start":"2011-03-09T11:45:00-08:00","end":"2011-03-09T12:00:00-08:00","title":"Brad Wicker","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299699900","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299700800"},{"id":"4866","start":"2011-03-09T12:00:00-08:00","end":"2011-03-09T13:00:00-08:00","title":"Janice Potters","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299700800","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299704400"},{"id":"4867","start":"2011-03-09T13:00:00-08:00","end":"2011-03-09T13:15:00-08:00","title":"Jacqui Chan","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299704400","email":"jc#rebelfrontier.net","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299705300"},{"id":"4876","start":"2011-03-09T13:15:00-08:00","end":"2011-03-09T13:30:00-08:00","title":"Mary Thacker","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299705300","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299706200"},{"id":"4868","start":"2011-03-10T10:15:00-08:00","end":"2011-03-10T11:15:00-08:00","title":"Trisha Roberts","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299780900","email":"trb483408#gmail.com","home_ph":"604-555-5555","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299784500"},{"id":"4870","start":"2011-03-10T11:30:00-08:00","end":"2011-03-10T12:30:00-08:00","title":"Jenson Bryant","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299785400","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299789000"},{"id":"4872","start":"2011-03-10T12:45:00-08:00","end":"2011-03-10T13:00:00-08:00","title":"Jenson Bryant","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299789900","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299790800"},{"id":"4873","start":"2011-03-10T13:00:00-08:00","end":"2011-03-10T13:15:00-08:00","title":"Jenson Bryant","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299790800","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299791700"},{"id":"4874","start":"2011-03-10T13:15:00-08:00","end":"2011-03-10T14:15:00-08:00","title":"Simon Chalk","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299791700","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299795300"},{"id":"4875","start":"2011-03-11T10:15:00-08:00","end":"2011-03-11T11:15:00-08:00","title":"Karen Walker","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299867300","email":"karenwalker#officesurplusdirect.net","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299870900"},{"id":"4877","start":"2011-03-11T12:00:00-08:00","end":"2011-03-11T12:15:00-08:00","title":"Amanda Brenner","service":"Women's Haircut","service_id":"65","client_note":"","stylist_note":"","utc_start":"1299873600","email":"amandab#coastfitness.com","home_ph":"555-235-2366","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299874500"},{"id":"4878","start":"2011-03-11T12:30:00-08:00","end":"2011-03-11T13:30:00-08:00","title":"Arnold Fieldman","service":"Men's haircut","service_id":"61","client_note":"","stylist_note":"","utc_start":"1299875400","email":"","home_ph":"","mobile_ph":"","work_ph":"","work_ext":"","utc_end":"1299879000"}], "next_page_num":"7"}
This is not a Sencha Touch specific issue: there are limits on the size of Ajax response that mobile safari can handle: see Too large an AJAX response for mobile safari?
Update: apparently this is not a mobile safari problem, this is a cellular network problem. Some networks will helpfully "paginate" the Ajax call -- thinking it's a regular web page download. Can you check to see if this is still the case on a wifi network?
After much head banging it appears that Sencha Touch stores only work well with up to approximately 10,000 characters I'm guess 8192 + the json delimiters?
After that it seems to start losing part of the data for us.
Can anyone else corroborate this?

Resources