PDA

View Full Version : JsonReader crashes when load has no data and root is undefined



rgralhoz
23 Oct 2013, 3:50 PM
Ext 3.1.1
JsonReader crashes when the responseText is similar to this:
"{"devices":{"@total":"0"}}"

And root property is "devices.device"

I have a fix for this issue, I'll post it here in a few minutes. :-)

rgralhoz
23 Oct 2013, 4:02 PM
This fix was tested at runtime on the latest Chrome. Please let me know if you find an issue with it.



/** * Fix for extjs3 JsonReader when root is defined like "myRoot.myProperty" and result is empty
* Just add a check for 'root' before using root.length
*
* http://www.sencha.com/forum/showthread.php?274536
* @author rgralhoz
*/
Ext.override(Ext.data.JsonReader, {


readRecords: function (o){
/**
* After any data loads, the raw JSON data is available for further custom processing. If no data is
* loaded or there is a load exception this property will be undefined.
* @type Object
*/
this.jsonData = o;
if(o.metaData){
this.onMetaChange(o.metaData);
}
var s = this.meta, Record = this.recordType,
f = Record.prototype.fields, fi = f.items, fl = f.length, v;


var root = this.getRoot(o),
c = root && root.length, /*fix for ext issue here */
totalRecords = c, success = true;


if(s.totalProperty){
v = parseInt(this.getTotal(o), 10);
if(!isNaN(v)){
totalRecords = v;
}
}
if(s.successProperty){
v = this.getSuccess(o);
if(v === false || v === 'false'){
success = false;
}
}


// TODO return Ext.data.Response instance instead. @see #readResponse
return {
success : success,
records : this.extractData(root, true), // <-- true to return [Ext.data.Record]
totalRecords : totalRecords
};
},






extractData: function (root, returnRecords) {
// A bit ugly this, too bad the Record's raw data couldn't be saved in a common property named "raw" or something.
var rawName = (this instanceof Ext.data.JsonReader) ? 'json' : 'node';


var rs = [];


// Had to add Check for XmlReader, #isData returns true if root is an Xml-object. Want to check in order to re-factor
// #extractData into DataReader base, since the implementations are almost identical for JsonReader, XmlReader
if (this.isData(root) && !(this instanceof Ext.data.XmlReader)) {
root = [root];
}
var f = this.recordType.prototype.fields,
fi = f.items,
fl = f.length,
rs = [];
if (returnRecords === true) {
var Record = this.recordType;


/*fix for ext issue here */
for (var i = 0; root && i < root.length; i++) {
var n = root[i];
var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
record[rawName] = n; // <-- There's implementation of ugly bit, setting the raw record-data.
rs.push(record);
}
}
else {
for (var i = 0; i < root.length; i++) {
var data = this.extractValues(root[i], fi, fl);
data[this.meta.idProperty] = this.getId(root[i]);
rs.push(data);
}
}
return rs;
}


});