Hi,
We've come across a scenario that is causing problems for us and I'd like your advise on how you would expect this situation to be handled.
We have a number of async processes (such as loading data) that interact with the grid and store instances once the promise resolves. However, if the grid or store has been destroyed while that promise is waiting, once it resolves we get errors when it tries to interact with the grids properties or methods. As far as I can tell, when something is destroyed it removes all properties from that instance, which is why we see "Cannot read properties of null" errors.
What do you suggest we do in these scenarios? Should we be checking that the grid is not destroyed every time a something resolves?
I have put together an example using the Tree Grid demo. There are two buttons in the toolbar "Async Thing" and "Destroy". If you press "Async Thing" it triggers a setTimeout
for 5 seconds which will eventually call a method on the grid. If you press "Destroy" before the timeout resolves, you end up getting an error in the console.
import { TreeGrid, GridRowModel } from '../../build/grid.module.js?463787';
import shared from '../_shared/shared.module.js?463787';
class Gate extends GridRowModel {
static get fields() {
return [{
name : 'capacity',
type : 'number'
}, 'domestic', 'airline', 'manager'];
}
}
// Transform a parent node to a leaf node when all its children are removed
Gate.convertEmptyParentToLeaf = true;
const tree = new TreeGrid({
appendTo : 'container',
features : {
cellEdit : true,
filter : true,
rowReorder : true,
stripe : true
},
loadMask : 'Loading tree data...',
columns : [
{ text : 'Id', field : 'id', width : 40, editor : false },
{ text : 'ParentIndex', field : 'parentIndex', width : 40, hidden : true },
{
text : 'Name',
field : 'name',
flex : 3,
type : 'tree',
touchConfig : { editor : false }
// You can customize expand/collapse icons
// expandIconCls : 'b-fa b-fa-plus-square',
// collapseIconCls : 'b-fa b-fa-minus-square'
},
{ type : 'aggregate', text : 'Capacity', field : 'capacity', flex : 1 },
{ text : 'Domestic', field : 'domestic', flex : 1 },
{ text : 'Airline', field : 'airline', flex : 1 },
{ text : 'Responsible<br/>Manager', field : 'manager', width : 100, htmlEncodeHeaderText : false }
],
store : {
modelClass : Gate,
readUrl : 'data/kastrup-airport.json',
autoLoad : true
},
handleAsyncActionComplete: () => {
console.log('async action complete!');
},
tbar : [
{
type : 'button',
ref : 'customButton',
icon : 'b-fa-folder-open',
pressedIcon : 'b-fa-plane',
text : 'Use custom tree icons',
toggleable : true,
onToggle({ pressed }) {
tree.store.readUrl = 'data/' + (pressed ? 'ohare-airport.json' : 'kastrup-airport.json');
tree.element.classList[pressed ? 'add' : 'remove']('ohare-airport');
tree.store.load();
}
},
{
type : 'button',
ref : 'expandAllButton',
icon : 'b-fa b-fa-angle-double-down',
text : 'Expand all',
onAction : () => tree.expandAll()
},
{
type : 'button',
ref : 'collapseAllButton',
icon : 'b-fa b-fa-angle-double-up',
text : 'Collapse all',
onAction : () => tree.collapseAll()
},
{
type : 'button',
text : 'Async Thing',
onAction : () => setTimeout(() => grid.handleAsyncActionComplete(), 5000)
},
{
type : 'button',
text : 'Destroy',
onAction : () => tree.destroy()
}
]
});
I would appreciate any suggestions you have for how to handle these situations
Thanks.