PDA

View Full Version : json data 'lints' but Touch fails to parse it?



rmitchell62@me.com
16 Jan 2011, 4:54 AM
Ok I can connect to a server and pull the following json data (hand crafted sample data). It lints ok.



{"sizes" :[
{"size" : "0",
"colours" : [
{"outputSku" : "1234-0-50","colourId" : "50", "colourName" : "Navy blue", "swatchRGB":"#000080"},
{"outputSku" : "1234-0-51","colourId" : "51", "colourName" : "Candy apple red", "swatchRGB":"#FF0800"},
{"outputSku" : "1234-0-52","colourId" : "52", "colourName" : "Atomic tangerine", "swatchRGB":"#FF9966"},
{"outputSku" : "1234-0-53","colourId" : "53", "colourName" : "Vanilla", "swatchRGB":"#F3E5AB"}] },
{"size" : "2",
"colours" : [
{"outputSku" : "1234-2-50","colourId" : "50", "colourName" : "Navy blue", "swatchRGB":"#000080"},
{"outputSku" : "1234-2-51","colourId" : "51", "colourName" : "Candy apple red", "swatchRGB":"#FF0800"},
{"outputSku" : "1234-2-52","colourId" : "52", "colourName" : "Atomic tangerine", "swatchRGB":"#FF9966"},
{"outputSku" : "1234-2-53","colourId" : "53", "colourName" : "Vanilla", "swatchRGB":"#F3E5AB"},
{"outputSku" : "1234-2-54","colourId" : "54", "colourName" : "Jade", "swatchRGB":"#00A86B"}] },
{"size" : "5",
"colours" : [
{"outputSku" : "1234-5-51","colourId" : "51", "colourName" : "Candy apple red", "swatchRGB":"#FF0800"},
{"outputSku" : "1234-5-52","colourId" : "52", "colourName" : "Atomic tangerine", "swatchRGB":"#FF9966"},
{"outputSku" : "1234-5-53","colourId" : "53", "colourName" : "Vanilla", "swatchRGB":"#F3E5AB"},
{"outputSku" : "1234-5-54","colourId" : "54", "colourName" : "Jade", "swatchRGB":"#00A86B"}] },
{"size" : "8",
"colours" : [
{"outputSku" : "1234-8-50","colourId" : "50", "colourName" : "Navy blue", "swatchRGB":"#000080"},
{"outputSku" : "1234-8-51","colourId" : "51", "colourName" : "Candy apple red", "swatchRGB":"#FF0800"},
{"outputSku" : "1234-8-53","colourId" : "53", "colourName" : "Vanilla", "swatchRGB":"#F3E5AB"},
{"outputSku" : "1234-8-54","colourId" : "54", "colourName" : "Jade", "swatchRGB":"#00A86B"}] }
]}



My model/store/proxy is:




Ext.regModel("sizes",{
fields: ['size'],
hasMany: {model:'colours', name:'colours'}
});

Ext.regModel("colours", {
fields: [
'outputSku','colourId','colourName','swatchRGB'
],
belongsTo: "sizes"
});



var gSC_sessionUuid='';


function getSizeColour(){


relatedSku = Ext.getCmp('fSCSearchFld').getValue();
var gSC_store = new Ext.data.Store({
model: 'sizes',
proxy: {
type: 'ajax',
url: '/json/1234',
reader: {
type: 'json',
root: 'sizes',
}
}
});
gSC_store.load();
}



but when I load I get:



XHR finished loading: "http://192.168.10.19/json/1234?_dc=1295178740553&limit=25".
sencha-touch-debug.js:9759Uncaught Ext.data.JsonReader.getResponseData: Unable to parse JSON returned by Server.
Ext.data.JsonReader.Ext.extend.getResponseDatasencha-touch-debug.js:9759
Ext.data.Reader.Ext.extend.readsencha-touch-debug.js:9441
(anonymous function)sencha-touch-debug.js:8707
Ext.data.Connection.Ext.extend.onCompletesencha-touch-debug.js:17495
Ext.data.Connection.Ext.extend.onStateChangesencha-touch-debug.js:17442
(anonymous function)sencha-touch-debug.js:3421


I've tried tracing down through the call stack to see what's going on but I get to:





14524
14525 Ext.util.JSON = {
14526 encode : function(o) {
14527 return JSON.stringify(o);
14528 },
14529
14530
decode : function(s) {
14531
return JSON.parse(s);
14532 }
14533 };
14534



and can't step any further. 'Step into' from here just takes me back to the exception handler. Is this where you are calling native browser code to decode? Has the model come into play at this point?
If anyone can point to an error in the model or JSON I'd appreciate it.

I'm on Ubuntu 10.10 running in chrome but the same fault on win7 with Safari. (Firefox/Ubuntu doesn't show anything at all)

Thanks
Rob

jep
16 Jan 2011, 7:16 PM
Rob - Right off the bat I can't spot anything wrong, but models and stores aren't my strong suit. If you post a simple standalone test app so I can just copy and fiddle with it, I'll certainly give it a shot.

rmitchell62@me.com
16 Jan 2011, 8:52 PM
Jep,
Thanks for responding.

I build a small sample, using my data, model, and the 'memory' proxy rather than json. It's here:



<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">

<!-- Sencha Touch CSS -->
<link rel="stylesheet" href="sencha-touch.css" type="text/css">

<!-- Sencha Touch JS -->
<script type="text/javascript" src="sencha-touch-debug.js"></script>

<script>

Ext.regModel("sizes",{
fields: ['size'],
hasMany: {model:'colours', name:'colours'}
});

Ext.regModel("colours", {
fields: [
'outputSku','colourId','colourName','swatchRGB'
],
belongsTo: "sizes"
});

var data =
{"sizes" :[
{"size" : "0",
"colours" : [
{"outputSku" : "1234-0-50","colourId" : "50", "colourName" : "Navy blue", "swatchRGB":"\#000080"},
{"outputSku" : "1234-0-51","colourId" : "51", "colourName" : "Candy apple red", "swatchRGB":"\#FF0800"},
{"outputSku" : "1234-0-52","colourId" : "52", "colourName" : "Atomic tangerine", "swatchRGB":"\#FF9966"},
{"outputSku" : "1234-0-53","colourId" : "53", "colourName" : "Vanilla", "swatchRGB":"\#F3E5AB"}] },
{"size" : "2",
"colours" : [
{"outputSku" : "1234-2-50","colourId" : "50", "colourName" : "Navy blue", "swatchRGB":"\#000080"},
{"outputSku" : "1234-2-51","colourId" : "51", "colourName" : "Candy apple red", "swatchRGB":"\#FF0800"},
{"outputSku" : "1234-2-52","colourId" : "52", "colourName" : "Atomic tangerine", "swatchRGB":"\#FF9966"},
{"outputSku" : "1234-2-53","colourId" : "53", "colourName" : "Vanilla", "swatchRGB":"\#F3E5AB"},
{"outputSku" : "1234-2-54","colourId" : "54", "colourName" : "Jade", "swatchRGB":"\#00A86B"}] },
{"size" : "5",
"colours" : [
{"outputSku" : "1234-5-51","colourId" : "51", "colourName" : "Candy apple red", "swatchRGB":"\#FF0800"},
{"outputSku" : "1234-5-52","colourId" : "52", "colourName" : "Atomic tangerine", "swatchRGB":"\#FF9966"},
{"outputSku" : "1234-5-53","colourId" : "53", "colourName" : "Vanilla", "swatchRGB":"\#F3E5AB"},
{"outputSku" : "1234-5-54","colourId" : "54", "colourName" : "Jade", "swatchRGB":"\#00A86B"}] },
{"size" : "8",
"colours" : [
{"outputSku" : "1234-8-50","colourId" : "50", "colourName" : "Navy blue", "swatchRGB":"\#000080"},
{"outputSku" : "1234-8-51","colourId" : "51", "colourName" : "Candy apple red", "swatchRGB":"\#FF0800"},
{"outputSku" : "1234-8-53","colourId" : "53", "colourName" : "Vanilla", "swatchRGB":"\#F3E5AB"},
{"outputSku" : "1234-8-54","colourId" : "54", "colourName" : "Jade", "swatchRGB":"\#00A86B"}] }
]}







function getSizeColour(){


var gSC_store = new Ext.data.Store({
model: 'sizes',
proxy: {
type: 'memory',
data: data,
reader: {
type: 'json',
root: 'sizes',
record: 'colours'
}
}
});
gSC_store.load();
}


Ext.setup({
// tabletStartupScreen: 'tablet_startup.png',
// phoneStartupScreen: 'phone_startup.png',
// icon: 'icon.png',
glossOnIcon: true,

onReady: function() {
getSizeColour();
}
});


</script>


</head>
<body></body>
</html>




Problem is, this code works! I changed the real app to use a memory proxy rather than ajax and it works as expected.

So
proxy: {
type: 'memory',
data: data,
reader: {
type: 'json',
root: 'sizes',
record: 'colours'
}

works but:
proxy: {
type: 'ajax',
url: '/json/1234',
reader: {
type: 'json',
root: 'sizes',
record: 'colours'
}

fails as described in my first post. (data is found, fetched and lints)

Not sure what more I can do to hunt this down - it looks like a bug or incompatibility to me. If I don't find anything or hear from the Sencha folks, I'll move it in to the bugs folder and move on. This is unfortunate because I want to use json/ajax models as a basis for the app rather than perl scripts on the host sending back html directly.

jep
16 Jan 2011, 10:01 PM
I think there are several things wrong with your code. For one, the use of the "records" config property. I think there are others, but perhaps it's best to try to just point you to the example here:

http://dev.sencha.com/deploy/touch/docs/?class=Ext.data.Reader

This example is almost exactly like you're trying to do, and works fine using ajax for me (I even tried changing "rest" to "ajax" and had no problems). I think perhaps you should try this example and work backwards, trimming out what you don't need, changing the field names to yours, etc.

Let me know if you still can't get it working.

rmitchell62@me.com
16 Jan 2011, 10:23 PM
Thanks for responding.

The use of 'record' is specified in the jsonreader doc.



"In the case above the record data is nested an additional level inside the "users" array as each "user" item has additional metadata surrounding it ('id' and 'value' in this case). To parse data out of each "user" item in the JSON above we need to specify the record configuration like this:

reader: {
type : 'json',
root : 'users',
record: 'user'
}
"


In any event, removing 'record' doesn't work either, I have tried it according to all of the examples I could find. And of course when the data is already in memory, parsing works without error. (at least with 'record' specified - not sure about without it)

You mentioned other errors in my code, would love to know what they are.
Thanks
Rob

jep
16 Jan 2011, 10:26 PM
I understand what the record field is, I just don't think you want to be using it in your code.

Did you look at the example I linked and see that it was very similar to yours?

object -> array -> object -> array

Second question - what are you expecting to get as the result as the store.data.items? Are you expecting a top level item for each item in the sizes array? This would correspond with that example. Perhaps it would be helpful to explain what you were expecting and then I could be more helpful on the problems I think I see with your code.

rmitchell62@me.com
17 Jan 2011, 12:35 PM
Solved

The problem was not in the js code. The file that contained the json on the server had an extra nonprintable character at the end. This is why the json worked in a memory object (cut and pasted into the code) but not when fetched from a file on a server. I don't know what the characters were (probably newline). So if you are putting test JSON data in a file, be careful!

It would be nice to see more information from the browser as to what is failing in JSON.parse as finding this bug to far too long.
Rob

jep
17 Jan 2011, 12:42 PM
That would explain why it was working 100% fine when I copied your JSON and saved it to a file for my local webserver. The editor must have scrubbed out whatever bad character you were running into. I don't think its newlines, as I had newlines in mine and it didn't ever have any problem. I also assume whenever you linted it, you didn't actually point the lint program to your server but instead copy/pasted it in (since your webserver probably wasn't publicly accessible). That would also explain it.

Glad you figured it out!