PDA

View Full Version : Ext.tab.Panel.removeAll(): me.store is null



seam_cw
11 Aug 2011, 10:37 PM
Simply explained: If calling removeAll() on a Ext.tab.Panel instance, this error occours:

"me.store is null"

It's from this line, in the refresh method of Ext.view.AbstractView:
records = me.store.getRange();

I tried to debug it a whole day long could not find a solution.

skirtle
12 Aug 2011, 4:00 AM
First up, an explanation of the error. When you call removeAll() it will destroy all of the child components. You cannot then interact with one of those components, they must be discarded. In this case it appears that something is trying to interact with a destroyed view component which, by virtue of being destroyed, no longer has a store.

Do you have any listeners in your code that might be trying to interact with the destroyed components? Perhaps a listener for tab change events?

What sort of components do you have inside your tabs? I realize you might have lots, just give us a general overview. Which of them have stores? A grid perhaps?

For diagnostic purposes, try replacing your call to tab.removeAll() with:


tab.remove(0);

then try:


tab.remove(1);

and so on for each of your tabs. See which ones cause the error and which don't. Does it matter which tab is currently active?

Next thing to try. Turn on 'Break On Errors' and inspect the variable me at the time of the error. Can you work out which component it corresponds to?

Next, work your way up the stacktrace. Make sure you're using a debug version of ExtJS for this (i.e. any of the versions which have the ExtJS code human readable). Somewhere in that stacktrace you'll find what is trying to interact with the destroyed component.

I would recommend trying different debuggers. Firebug, the Chrome Developer Tools and the IE debugger are all slightly different and you may have more luck with one than the others.

As well as the information I've requested above it may also help to provide the following.

Exact ExtJS version.
The stacktrace.
A simple reproducible test case or, failing that, some snippets from your code that might help point us in the right direction.
Whether or not this happens in different browsers or only in one browser.

mankz
12 Aug 2011, 4:06 AM
Just tried this in the Ext 4.0.5 tabs example.

Just calling



tabs.removeAll();


breaks it (though different error). Not sure what the expected result would be, tab panel with no tabs seems .... not so useful :)

seam_cw
12 Aug 2011, 4:26 AM
While debugging I found out, what skirtle already mentioned: the removeAll() doesn't trigger the error directly. If I print some messages using console.log() after the removeAll(), they appear before the "me.store is null" error.

The error only occours if a grid is displayed inside the tab. I couldn't find out yet, which listener or component tries to interact with the tabs contents, but it's at least a hint.

skirtle
12 Aug 2011, 4:44 AM
The stacktrace should reveal all. Could you post it?

mankz
12 Aug 2011, 4:49 AM
Actually, in 4.0.5 tabs sample this works ok. The error I saw was caused by another small bug.

1. Create tab with autoLoad : true,
2. Render it and instantly call removeAll on the tab panel - i.e. destroy it while it's loading.
3. The ajax request completes and tries to update the dom, *crash*

seam_cw
12 Aug 2011, 5:08 AM
The stacktrace should reveal all. Could you post it?

It's from a german version of Firebug, but the essentials should be clear ("Zeile" means "line"):

me.store is null
refresh()ext-all-debug.js (Zeile 58564)
callParent(args=[])ext-all-debug.js (Zeile 2833)
refresh()ext-all-debug.js (Zeile 67526)
callParent(args=[])ext-all-debug.js (Zeile 2833)
refresh()ext-all-debug.js (Zeile 76013)
callParent(args=[])ext-all-debug.js (Zeile 2833)
refresh(firstPass=undefined)ext-all-debug.js (Zeile 76396)
refresh()ext-all-debug.js (Zeile 75572)
[Bei diesem Fehler anhalten] record

The Ext version is 4.0.2.

skirtle
12 Aug 2011, 5:27 AM
For some reason not all of my line numbers tie up with yours. What's on line 75572 for you?

Is there any chance you could post the Chrome stacktrace too? They're generally a little easier to follow in my experience.

seam_cw
12 Aug 2011, 5:40 AM
The one of Chrome isn't much better:

Uncaught TypeError: Cannot call method 'getRange' of null
Ext.define.refresh ext-all-debug.js:58564
Base.callParent ext-all-debug.js:2833
Ext.define.refresh ext-all-debug.js:67526
Base.callParent ext-all-debug.js:2833
Ext.define.refresh ext-all-debug.js:76013
Base.callParent ext-all-debug.js:2833
Ext.define.refresh ext-all-debug.js:76396
me.refresh ext-all-debug.js:75572

Line 75572 is the me.refresh(); call in initComponent of Ext.view.Table:


Ext.define('Ext.view.Table', {
extend: 'Ext.view.View',

[...]

initComponent: function() {
var me = this;

if (me.deferRowRender !== false) {
me.refresh = function() {
delete me.refresh;
setTimeout(function() {
me.refresh();
}, 0);
};
}

skirtle
12 Aug 2011, 6:08 AM
I can reproduce it now.

Seems to be a bug in 4.0.2. Works fine in 4.0.5 (you'll need a support contract to get 4.0.5).

What happens is that removeAll() removes the tabs in order. As each one is removed, the next tab becomes the active tab. When the grid becomes the active tab it initiates a deferred refresh. By the time the refresh actually happens the grid has been destroyed.

There are a number of ways you could work around it. If you can cope with the performance hit then the easiest way is to set deferRowRender: false on your grid. One alternative is to remove the grid's tab first, then call removeAll(). If you have multiple grid tabs then you'll want to remove all of them up front before you remove the active tab.

seam_cw
15 Aug 2011, 9:58 PM
Thanks for all the replies.
@skirtle: I couldn't solve it this way, both solutions didn't change anything. I changed the loading behaviour and now it works without errors. Probably some other part of the code tried to work at the grid, while it wasn't thtere anymore.

bigal488
28 Sep 2011, 7:47 AM
adding deferredRender: false
to the tab panel config did the trick for me using ExtJS 4.0.2a