PDA

View Full Version : [OPEN-432][3.??] Issue with Ext.data.DataReader realize method



mlitcher
15 Jan 2010, 10:57 AM
I believe there may be a bug in the Ext.data.DataReader.realize method. I'm currently using Ext 3.1 public release, and have tested in IE6, IE8, and FF3.5.

The orginal symptom I was experiencing had to with row selections after creating a new record and receiving the database primary key (automated via JsonWriter). The symptoms are very simliar to those described here (http://www.extjs.com/forum/showthread.php?p=324346#post324346).

After some debugging, I could see that the Ext.data.Store.onCreateRecords method was not successfully remapping the keys, however, the reader was "realizing" the records.

I have a reader/writer/store configured as follows:



var reader = new Ext.data.JsonReader({
totalProperty: "total",
successProperty: "success",
messageProperty: "message",
idProperty: "id",
root: "data"
},[
{name: "id"},
{name: "name"},
{name: "active"}
]);

var writer = new Ext.data.JsonWriter({
encode: true,
listful: true,
writeAllFields: true
});

var store = new Ext.data.Store({
url: "controller.aspx",
autoDestroy: true,
batch: true,
baseParams: {cmd: "ManageInstances"},
reader: reader,
writer: writer,
pruneModifiedRecords: true
});


My server responds to a create action with something like:



{"success":true,"data":[{"id":99,"name":"test","active":true}],"message":"Record created."}


In the method onCreateRecords, reMap is called with an empty array.



onCreateRecords : function(success, rs, data) {
if (success === true) {
try {
this.reader.realize(rs, data); // rs and data both altered in realize method and become empty
this.reMap(rs); // this call is made with an empty array
}
catch (e) {
this.handleException(e);
if (Ext.isArray(rs)) {
this.onCreateRecords(success, rs, data);
}
}
}
}


In the DataReader.realize method, in the recursive portion, both "rs" and "data" are being spliced/shifted when passed as arrays, altering the variables.



realize: function(rs, data) {

if (Ext.isArray(rs)) {

for (var i = rs.length - 1; i >= 0; i--) {

if (Ext.isArray(data)) {
this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift());
}
else {
this.realize(rs.splice(i,1).shift(), data);
}
}
}
else {

...
}
}


As a result, the records are realized properly, but unable to be remapped in the onCreateRecords method. If I change this code to the following, everything works as expected (in my case at least).



realize: function(rs, data) {

if (Ext.isArray(rs)) {

for (var i = rs.length - 1; i >= 0; i--) {

if (Ext.isArray(data)) {
this.realize(rs[i], data[i]);
}
else {
this.realize(rs[i], data);
}
}
}
else {

...

}
}


I'm not sure if there are any other ramifications of making this change, but it solved my immediate row selection issue because the records were remapped properly.

Here's the full override that I implemented:



Ext.override(Ext.data.DataReader, {

realize: function(rs, data) {

if (Ext.isArray(rs)) {

for (var i = rs.length - 1; i >= 0; i--) {

if (Ext.isArray(data)) {
this.realize(rs[i], data[i]);
}
else {
this.realize(rs[i], data);
}
}
}
else {

if (Ext.isArray(data) && data.length == 1) {
data = data.shift();
}
if (!this.isData(data)) {
throw new Ext.data.DataReader.Error('realize', rs);
}

rs.phantom = false;
rs._phid = rs.id;
rs.id = this.getId(data);

rs.fields.each(function(f) {
if (data[f.name] !== f.defaultValue) {
rs.data[f.name] = data[f.name];
}
});

rs.commit();
}
}
});


I hope I've described the issue in enough detail. Any thoughts?

Thanks!

Jamie Avins
15 Jan 2010, 11:20 AM
Plenty of detail, I'll enter this in Trac and look into it.

mg_cristi
8 Feb 2010, 9:42 AM
I also have this problem

I fixed it by replacing the onCreateRecords in Store.js



onCreateRecords : function(success, rs, data) {
if (success === true) {
try {
var oldIds = [];

Ext.each(rs, function (record) {
oldIds.push(record.id);
});

this.reader.realize(rs, data);

rs = [ ];

Ext.each(oldIds, function (id) {
var record = this.getById(id);

if (record) {
rs.push(record);
}
}, this);

this.reMap(rs);
}
catch (e) {
this.handleException(e);
if (Ext.isArray(rs)) {
// Recurse to run back into the try {}. DataReader#realize splices-off the rs until empty.
this.onCreateRecords(success, rs, data);
}
}
}
}

Jamie Avins
23 Feb 2010, 12:27 PM
SVN 6142 reverted an issue caused by an earlier commit that should be the cause of this issue. Can you test with the latest SVN and see if that resolved your problem?

mlitcher
23 Feb 2010, 8:18 PM
I pulled down and built the latest 3.1.x branch, but unfortunately, I'm still seeing the original symptoms. I checked the store before and after a create and it still looks like the new records are not being remapped properly.

tonedeaf
6 Apr 2010, 10:44 PM
Wanted to confirm that this bug still exists with the released ExtJS 3.2.0
onCreateRecords(): The key is not remapped, even though the record is realized and new primary key is applied to the record id.

Please fix this bug in the latest release.

sumit.madan
27 Aug 2010, 4:04 AM
Still not fixed in 3.2.2

This bug is well understood and it will be encountered while creating new records in store on mapped dataIndexes.

Please expedite this bug fix.

wang888
28 Aug 2010, 1:46 AM
This bug is well understood and it will be encountered while creating new records in store on mapped dataIndexes.

mankz
20 Jun 2011, 6:59 AM
I still see this bug in 3.4.0