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(); } }