PDA

View Full Version : Error (a is null, d is undefined) related to store and gridpanel



infernoz
18 May 2012, 2:34 PM
Hello,

I have a gridpanel that is backed by a store. I have methods available to populate the store (and by associated the grid) via server requests.

I noticed that when records are in the grid and I click any of them with my mouse, the next time I try to remove all elements and refresh the store/grid with new data, or possibly just clear all data. I receive the following errors:

In Firefox 12

first error I receive
a is null


...MouseUp:function(k){var j=this,a=j.getEventXY(k),b=j.series.items,d,h,c,g;if(j.e...

second error
d is undefined


...MouseUp:function(k){var j=this,a=j.getEventXY(k),b=j.series.items,d,h,c,g;if(j.e...



In IE
Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; InfoPath.3; MS-RTC LM 8)
Timestamp: Fri, 18 May 2012 22:25:51 UTC

First Error received
Message: 'viewIndex' is null or not an object
Line: 21
Char: 676249
Code: 0
URI: http://localhost:8080/extjs/ext-all.js

Second Error
Message: 'undefined' is null or not an object
Line: 21
Char: 941412
Code: 0
URI: http://localhost:8080/extjs/ext-all.js







To reiterate, this only occurs after I click on the grid panel. Here is my store, grid panel, and form (which contains logic to reset and repopulate the grid). I tried changing my calls to store.removeAll(false) to true but this did not solve the issue.

//store

Ext.define('DMT.store.OrgStatisticsStore', {
extend: 'Ext.data.Store',
model: 'DMT.model.OrgStatisticsModel',
alias : 'widget.OrgStatisticsStore',
storeId: 'orgStatisticsStore',

proxy: {
type: 'ajax',
url: '/DMT/submit.html',
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json',
root: 'data',
encode: true,
writeAllFields: true
},
extraParams: {'processorType': 'orgStatistics'}
}
});

//grid

Ext.require(['Ext.window.MessageBox',
'DMT.view.OrgStatisticsSearchForm']);

Ext.define('DMT.view.OrgStatisticsView' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.orgStatisticsView',
id: 'orgStatisticsView',
store: 'OrgStatisticsStore',
selType: 'cellmodel',
layout: 'fit',

/*, renderer: Ext.util.Format.dateRenderer('n/j/Y G:i:s')*/
initComponent: function() {
currentView = this;

var orgStatisticsStore = Ext.data.StoreManager.lookup('OrgStatisticsStore');
var orgStatisticsProxy = orgStatisticsStore.getProxy();

Ext.apply(this, {
plugins: [{
ptype: 'cellediting',
clicksToEdit: 1
}],

columns: {
items: [{header: 'ID', dataIndex: 'id', hidden: true, hideable: false},
{header: 'a_ID', dataIndex: 'a', hideable: false},
{header: 'b_ID', dataIndex: 'b', hideable: true},
{header: 'c_ID', dataIndex: 'c', hideable: true},
{header: 'd_ID', dataIndex: 'd', hideable: true},
{header: 'e_ID', dataIndex: 'e', hideable: true},
{header: 'f_ID', dataIndex: 'f', hideable: true},
{header: 'g_ID', dataIndex: 'g', hideable: true},
{header: 'ID_TYPE', dataIndex: 'idtype', hidden: true, hideable: false},
{header: 'DATA_SOURCE_ID', dataIndex: 'DataSourceId', hidden: true, hideable: false},
{header: 'START_DATE', dataIndex: 'startDate', hidden: true, hideable: false},
{header: 'END_DATE', dataIndex: 'endDate', hidden: true, hideable: false},
{header: 'UPDATE_DATE', dataIndex: 'updateDate', hidden: true, hideable: false},
{header: 'UPDATE_ID', dataIndex: 'updateId', hidden: true, hideable: false},
{header: 'STAT_CODE', dataIndex: 'statCode', /*width: 170,*/ flex: 3, hideable: false},
{header: 'STAT_VALUE', dataIndex: 'statValue', /*width: 170,*/ flex: 3, editor: 'textfield', hideable: false},
{header: 'DELETE', dataIndex: 'deleteRow', xtype: 'checkcolumn', /*width: 60*/ flex: 1, /*maxWidth: 60,*/ editor: 'checkbox', sortable: false, hideable: false}
],
defaults: {
flex: 2
}
},
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
ui: 'footer',
layout: {
type: 'hbox',
pack: 'start',
align: 'middle'
},
items: [
//Form which user can search for org stats data
{xtype: 'orgStatisticsSearchForm', width: 380, height: 110, x:0, y:10,
listeners: { 'afterrender': function() {
orgSearchForm = this;
searchButton = orgSearchForm.getComponent('orgStatsSearchButton');
}}},

//Sends updates
{ xtype: 'button', text: 'Submit', width: 80, maxWidth: 80,
initComponent: function() {
submitButton = this;
},
listeners: {
'click': function() {
orgStatisticsStore.on({
scope: currentView,
beforesync: currentView.disableButtons,
write: currentView.submitFinished
});
orgStatisticsProxy.on({
scope: currentView,
exception: currentView.showSubmitError
});

orgStatisticsStore.sync();
}}},

//Clears all data from grid
{ xtype: 'button', text: 'Clear', width: 80, maxWidth: 80,
initComponent: function() {
clearButton = this;
},
listeners: {
'click': function() {
currentView.disableButtons();
orgStatisticsStore.removeAll(false);
currentView.enableButtons();
}
}}
]
}]
});

this.callParent(arguments);
},

/**
* Function to disable all buttons in panel
*/
disableButtons: function(){
submitButton.disable(true);
clearButton.disable(true);
searchButton.disable(true);
},

/**
* Function to enable all buttons in panel
*/
enableButtons: function(){
submitButton.enable(true);
clearButton.enable(true);
searchButton.enable(true);
},

/**
* Function encapsulating the message that should be shown to users after
* a submit button response comes back from server successfully
*/
submitFinished: function() {
var messageBox = Ext.Msg.show({
title:'DMT Response',
msg: 'Changes have been successfully sent',
animateTarget: submitButton,
icon: Ext.Msg.INFO,
closable: false
});

setTimeout(function(){
messageBox.close();
}, 2700);

currentView.enableButtons();
},

/**
* Function encapsulating the message that should be shown to users after
* a submit button response comes back from server with a failure :(
*/
showSubmitError: function() {
var errorMessageBox = Ext.Msg.show({
title:'DMT Response',
msg: 'An error has occured while sending changes. Please contact support or try again.',
animateTarget: submitButton,
icon: Ext.Msg.ERROR,
closable: false
});

setTimeout(function(){
errorMessageBox.close();
}, 2700);

currentView.enableButtons();
}
});

//form - which allows searches and populates the grid panel with the search results

Ext.require(['DMT.view.OrgComboBox',
'DMT.view.IssueIdMultiSearchData']);

Ext.define('DMT.view.OrgStatisticsSearchForm' ,{
extend: 'Ext.form.Panel',
alias : 'widget.orgStatisticsSearchForm',
defaultType: 'textfield',
border: false,
layout: 'absolute',

initComponent: function () {
multiIdSearchArray = new Array();
this.callParent(arguments);
currentForm = this;
},

items: [
{ xtype: 'hiddenfield', name: 'processorType', value: 'orgStatisticsSearch'},
{ xtype: 'textfield', fieldLabel: 'Issue Id', name: 'issueId',
validateOnChange: false,
validateOnBlur: false,
x:0, y:0, width: '250',

//override validation for textfield
validator: function(value){

//value of text field doesnt matter if multi search is being done
if (multiIdSearchArray.length != 0) {
return true;
}

//value of text field is fine if its trimed value is not blank
if (Ext.String.trim(value) != '') {
return true;
}

//Failed validation otherwise
return 'Issue Id is required if Multi Id Search param is blank';
}
},
{ xtype: 'orgComboBox',
name: 'idType',
width: 250,
x:0,
y:25
},

//Button used to submit search to server and return results to org statistics grid panel
{ xtype: 'button', id: 'orgStatsSearchButton', text: 'Search', width: 80, x:275, y:23,
handler: function() {
var form = this.up('form').getForm();
if (form.isValid()) {
form.submit({scope: this, waitMsg:'Searching', url: '/DMT/search.html',
params: {issueArray: multiIdSearchArray},
success: function(form, action) {

var total = action.result.total;
if (total == 0) {
Ext.Msg.show({
title:'DMT Search',
msg: 'No data returned from search',
animateTarget: this,
icon: Ext.Msg.WARNING,
buttons: Ext.Msg.OK
});
}
else {
var orgStatisticsStore = Ext.data.StoreManager.lookup('OrgStatisticsStore');
orgStatisticsStore.removeAll(true);
orgStatisticsStore.add(action.result.data);
}
},
failure: function(form, action) {
Ext.Msg.show({
title:'DMT Search',
msg: 'An error has occured while searching for data. Please contact support or try again.',
animateTarget: this,
icon: Ext.Msg.ERROR,
buttons: Ext.Msg.OK
});
}
});
}
}
},

//Used to search for multiple org statistics at once. If this field is populated,
//it will override the search parameter that is specified in the text field above
{
xtype : 'textareafield',
name : 'Multi Id Search',
fieldLabel: 'Multi Id Search',
readOnly: true,
autoScroll: true,
width: 250,
height: 60,
listeners: {
'focus': function() {
if (multiIdSearchArray.length > 1) {
var someStuff = multiIdSearchArray[0];
var text = someStuff.issueId;
}
someWindow = Ext.widget('issueIdMultiSearchWindow', {
parentForm: currentForm
});
someWindow.show();
}
},
x:0, y:50
}
],

//Returns the array holding the multi search parameters that will searched
getMultiSearchArray: function () {
return multiIdSearchArray;
},

//Sets the textfield area and the array multiIdSearchArray in this form
setMultiSearchArray: function (multiSearchArray) {
var multiSearchTextArea = this.down('textareafield');
var newTextValue = '';

Ext.each(multiSearchArray, function(searchData, index, arrayItSelf) {
var issue = searchData.issueId;

if (newTextValue !== '') {
newTextValue = newTextValue + '\n';
}
newTextValue = newTextValue + issue
});

multiSearchTextArea.setValue(newTextValue);
multiIdSearchArray = multiSearchArray;
}
})

Thanks,

infernoz

scottmartin
18 May 2012, 9:46 PM
Have you tried tracing through you code .. in your listeners to see where it is getting lost?

Regards,
Scott.

infernoz
21 May 2012, 1:56 PM
I switched to ext-all-debug from ext-all and traced the code a bit. I'm getting a different error with ext-all-debug, which is 'node is null'.

It seems that the issue is coming about when I call orgStatisticsStore.add(action.result.data) in my form. The trace for this is below (a bit messy, I apologize though I'm not sure of a better way of presenting).


node is null
indexOf()ext-all-debug.js (line 61788)node = null



setPosition()ext-all-debug.js (line 83844)row = Object { phantom=false, internalId="ext-record-32", data={...}, more...}
col = Object { dataIndex="statValue", flex=3, hideable=false, more...}



onViewRefresh()ext-all-debug.js (line 83800)
fire()ext-all-debug.js (line 8586)
continueFireEvent()ext-all-debug.js (line 24623)eventName = "refresh"
args = [Object { deferInitialRefresh=true, scroll=true, xtype="gridview", more...}]
bubbles = undefined



fireEvent()ext-all-debug.js (line 24601)eventName = "refresh"



fireEvent()ext-all-debug.js (line 57133)ev = "refresh"



refresh()ext-all-debug.js (line 61364)
callParent(args=[])ext-all-debug.js (line 3728)
refresh()ext-all-debug.js (line 103408)
callParent(args=[])ext-all-debug.js (line 3728)
refresh()ext-all-debug.js (line 105748)
onAdd()ext-all-debug.js (line 61505)ds = Object { data={...}, groupers={...}, storeId="OrgStatisticsStore", more...}
records = [Object { phantom=false, internalId="ext-record-37", data={...}, more...}, Object { phantom=false, internalId="ext-record-38", data={...}, more...}, Object { phantom=false, internalId="ext-record-39", data={...}, more...}, 5 more...]
index = 0



callParent()ext-all-debug.js (line 3728)args = [Object { data={...}, groupers={...}, storeId="OrgStatisticsStore", more...}, [Object { phantom=false, internalId="ext-record-37", data={...}, more...}, Object { phantom=false, internalId="ext-record-38", data={...}, more...}, Object { phantom=false, internalId="ext-record-39", data={...}, more...}, 5 more...], 0, Object { scope={...}, refresh=function(), add=function(), more...}]



onAdd()ext-all-debug.js (line 106080)ds = Object { data={...}, groupers={...}, storeId="OrgStatisticsStore", more...}
records = [Object { phantom=false, internalId="ext-record-37", data={...}, more...}, Object { phantom=false, internalId="ext-record-38", data={...}, more...}, Object { phantom=false, internalId="ext-record-39", data={...}, more...}, 5 more...]
index = 0



fire()ext-all-debug.js (line 8586)
continueFireEvent()ext-all-debug.js (line 24623)eventName = "add"
args = [Object { data={...}, groupers={...}, storeId="OrgStatisticsStore", more...}, [Object { phantom=false, internalId="ext-record-37", data={...}, more...}, Object { phantom=false, internalId="ext-record-38", data={...}, more...}, Object { phantom=false, internalId="ext-record-39", data={...}, more...}, 5 more...], 0]
bubbles = undefined



fireEvent()ext-all-debug.js (line 24601)eventName = "add"



insert()ext-all-debug.js (line 50005)index = 0
records = [Object { phantom=false, internalId="ext-record-37", data={...}, more...}, Object { phantom=false, internalId="ext-record-38", data={...}, more...}, Object { phantom=false, internalId="ext-record-39", data={...}, more...}, 5 more...]



add()ext-all-debug.js (line 50046)records = [Object { phantom=false, internalId="ext-record-37", data={...}, more...}, Object { phantom=false, internalId="ext-record-38", data={...}, more...}, Object { phantom=false, internalId="ext-record-39", data={...}, more...}, 5 more...]



The add event that updates the data calls the event add which seems to screw up when it is looking for a valid row in the setPosition() function:

else if (row.isModel) { me.record = row;
me.row = view.indexOf(row); -- row ends up being null....

}

This definitely has something to do with the fact that I am calling removeAll() prior to adding the records, but I cant pinpoint why.

P.S. I'm using ExtJS 4.1.0

Cheers,

infernoz

infernoz
23 May 2012, 7:49 AM
What I believe solved the issue discussed above was adding the call gridPanel.getSelectionModel().deselectAll() after removing all rows from the grid via store.removeAll(false). I also added the same call prior to calling sync() on the store associated with the grid, though I dont know if this is needed.

If someone could tell me why this call is needed, or if this is the right way to solve my issue, your enlightenment is appreciated. But, in any case my a is null errors are no longer appearing.

Cheers,

infernoz