Issue description:
Am attempting to invalidate and re-fresh a SQL-based datasource-fed ListGrid with setAlwaysShowEditors = true.
Upon refresh, null pointer exception appears in client output. Issue does *not* occur when setAlwaysShowEditors = false.
In digging through the javascript, it appears there is either (a) a race condition between fetching data and redrawing the grid OR (b) a missing NULL check to prevent issue from occurring.
1. v8.3p_2013-02-24/PowerEdition Deployment (built 2013-02-24)
Although checked SmartClient v9.1 nightlies and same javascript code appears.
2. Firefox (version 26.0) and Chrome (latest version).
5. Stack trace:
Here is javascript source code (ISC_Grids.js) where the issue occurs:
As you can see there is no NULL check on _5 before it is accessed. In my browser debugging, when using breakpoints, getEditForm() was returning NULL but very soon after was actually returning a non-null value. What I think may be happening is that when the list grid is cleared (or invalidated) the editForm is cleared or becomes null...however once the data arrives, the editForm is re-initialized.
6. Code used to generate error
1) Create a ListGrid and a button
2) Set the ListGrid to use a SQL-based datasource
3) Setup the button so when clicked it calls a cancelEditing, invalidate, and fetchData
4) Press button. Then press button again. Observe error. Each time button is pressed, error occurs.
Here is source code to generate example:
DataSource file
SmartGWT Java code:
Am attempting to invalidate and re-fresh a SQL-based datasource-fed ListGrid with setAlwaysShowEditors = true.
Upon refresh, null pointer exception appears in client output. Issue does *not* occur when setAlwaysShowEditors = false.
In digging through the javascript, it appears there is either (a) a race condition between fetching data and redrawing the grid OR (b) a missing NULL check to prevent issue from occurring.
1. v8.3p_2013-02-24/PowerEdition Deployment (built 2013-02-24)
Although checked SmartClient v9.1 nightlies and same javascript code appears.
2. Firefox (version 26.0) and Chrome (latest version).
5. Stack trace:
Code:
ERROR: 15:19:00.877:TMR8:WARN:Log:TypeError: Cannot read property 'getItems' of null
Stack from error.stack:
ListGrid._clearingInactiveEditorHTML() @ SNAP/sc/modules/ISC_Grids.js:1092:343
GridBody.redraw() @ SNAP/sc/modules/ISC_Grids.js:607:48
[c]Canvas.clearRedrawQueue() @ SNAP/sc/modules/ISC_Core.js:2222:110
[c]Class.fireCallback() @ SNAP/sc/modules/ISC_Core.js:257:78
Timer._fireTimeout() @ SNAP/sc/modules/ISC_Core.js:943:81
<anonymous>:1:11() @
com.smartgwt.client.core.JsObject$SGWT_WARN: 15:19:00.877:TMR8:WARN:Log:TypeError: Cannot read property 'getItems' of null
Stack from error.stack:
ListGrid._clearingInactiveEditorHTML() @ SNAP/sc/modules/ISC_Grids.js:1092:343
GridBody.redraw() @ SNAP/sc/modules/ISC_Grids.js:607:48
[c]Canvas.clearRedrawQueue() @ SNAP/sc/modules/ISC_Core.js:2222:110
[c]Class.fireCallback() @ SNAP/sc/modules/ISC_Core.js:257:78
Timer._fireTimeout() @ SNAP/sc/modules/ISC_Core.js:943:81
<anonymous>:1:11() @
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:105)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
at java.lang.Thread.run(Thread.java:744)
Code:
isc.A.$69l = function isc_ListGrid__clearingInactiveEditorHTML(_1, _2) {
if (this.$69m == null)return;
if (!this.$286 || !this.$686((_2 != null ? this.getField(_2) : null), true))return;
if (_1 != null) {
var _3 = "_" + _1 + "_" + _2, _4 = this.$69m[_3];
if (_4) {
_4.formItem.clearInactiveEditorContext(_4);
delete this.$69m[_3]
}
} else {
var _5 = this.getEditForm(), _6 = _5.getItems();
for (var i = 0; i < _6.length; i++) {
_6[i].clearAllInactiveEditorContexts()
}
delete this.$69m
}
6. Code used to generate error
1) Create a ListGrid and a button
2) Set the ListGrid to use a SQL-based datasource
3) Setup the button so when clicked it calls a cancelEditing, invalidate, and fetchData
4) Press button. Then press button again. Observe error. Each time button is pressed, error occurs.
Here is source code to generate example:
DataSource file
Code:
<DataSource ID="task" serverType="sql" tableName="collection_task" dropExtraFields="true">
<fields>
<field name="id" type="sequence" hidden="true" primaryKey="true"/>
<field name="interface_id" type="integer" />
</fields>
</DataSource>
Code:
public class TestGrid extends VLayout {
private ListGridField _interfaceField;
protected ToolStrip _toolStrip;
public TestGrid() {
_interfacesGrid = new ListGrid();
_interfacesGrid.setDataSource(DataSource.get("task"));
_interfacesGrid.setWidth100();
_interfacesGrid.setHeight100();
_interfacesGrid.setAlwaysShowEditors(true);
_interfacesGrid.setAutoSaveEdits(false);
_toolStrip = new ToolStrip();
ToolStripButton button = new ToolStripButton("Apply Settings...");
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
refreshDataFromServer();
}
});
_toolStrip.addButton(button);
_toolStrip.addFill();
_toolStrip.setWidth100();
addMember(_toolStrip);
addMember(_interfacesGrid);
}
private void refreshDataFromServer() {
_interfacesGrid.discardAllEdits();
_interfacesGrid.invalidateCache();
_interfacesGrid.fetchData();
}
}