Question

I have an MVC application that works perfectly fine. However I keep getting this ext-all.js error - "Uncaught TypeError: Cannot call method 'getLeft' of undefined" when I move towards the left end of the UI.

The error seems harmless but I can't seem to figure the root cause(component) of what throws this.

Help is much appreciated!

Detailed error is as follows:

Uncaught TypeError: Cannot call method 'getLeft' of undefined ext-all.js:18
   Ext.define.isOnLeftEdge ext-all.js:18
   Ext.define.onHeaderCtMouseMove ext-all.js:18
   (anonymous function) VM1221:6
   g ext-all.js:18
Was it helpful?

Solution

You should use a dev/debug version of ext instead of compressed ext-all.js for debugging purpose (and conditional breakpoints and/or halt on exception feature of your debugger)... In your case, the faulty method is probably Ext.grid.column.Column#isOnLeftEdge.

The undefined thing on which the method is called is the element of the column. We can deduce that the problem is probably that your column is never rendered before this test occurs. Wouldn't that be a hidden column that has never been shown since the grid has been created? A very usual cause for a component's element being undefined is when some code is called with a delay, and the component has been destroyed between when the event was fired and when the handler is actually executed... But this is visibly not the case here.

Anyway, it seems like a glitch in Ext code base. This part of the lib (grid, view rendering, etc.) has been reworked a lot in 4.2.1 I think, so maybe updating your version of Ext would make the issue vanish. If you still need to stick to your version for some time, you could override the faulty method to prevent the error (that remains debugging noise), something like this:

Ext.define('Ext.ux.fix.Ext.grid.column.Column', {
    override: 'Ext.grid.column.Column'

    ,isOnLeftEdge: function(e) {
        return this.el && this.callParent(arguments);
    }
});

We can do that with pretty good confidence because we see that the calling method doesn't do anything special in case the header is not rendered, and it will behave the same if we return something falsy from isOnLeftEdge.

Finally, you should probably add a test of Ext's version in this file, to help keep your code clean when you eventually update your Ext. For example:

if (!Ext.getVersion().isLessThan('4.2')) alert('Retest me please!');

Update

And then, the same thing happens on the right edge... You can probably prevent the error with a similar patch. Unfortunately, you can probably expect yet another error after that. Look at the code of onHeaderCtMouseMove. If you return false for isOnLeftEdge and isOnRightEdge, the execution path will run down this line:

overHeader.el.dom.style.cursor = '';

Here again, it is expected that the header's element exist. And your errors indicate that in your particular case, it does not. You can prevent the whole situation from happening at once in exchange for a small overhead (because we're replicating some code that will be executed again in the super method):

Ext.define('Ext.ux.fix.Ext.grid.plugin.HeaderResizer', {
    override: 'Ext.grid.plugin.HeaderResizer'

    ,onHeaderCtMouseMove: function(e, t) {
        // we've got no problem when we're dragging
        if (!this.headerCt.dragging) {
            var headerEl = e.getTarget('.' + this.colHeaderCls, 3, true),
                overHeader = Ext.getCmp(headerEl.id);
            if (!overHeader.el) {
                // that's the crashy case, so we're stopping process here

                // ... but what about trying to understand how we could end
                // here in the first place? look around, there's something
                // to be found ;) !
                debugger

                return;
            }
        }
        // we're safe, continue
        this.callParent(arguments);
    }
});

Now that was the no-brainer way to a fix. But you'll probably want to try and understand what really happens... We can see that onHeaderCtMouseMove already tries to avoid processing unrendered column header:

headerEl = e.getTarget('.' + me.colHeaderCls, 3, true);

if (headerEl){
    overHeader = Ext.getCmp(headerEl.id);

This code probably expects the headerEl grabbed from the event and overHeader.el to be the same. And in your case, they are not, since headerEl passes the test, but overHeader.el is undefined. Why are they not the same? That's what you should investigate. If you plug my above code in, you'll get paused in the case that was crashing; that's where the answer lies...

OTHER TIPS

I also faced this problem. In my scenario(as mentioned in this link ), I was creating a templatecolumn dynamically in grid panel. I was giving id for each column and adding to grid as below:

var temp={
xtype:'templatecolumn',
id:'mycolumn',
tpl:'...'
}
//adding temp to grid panel

Suddenly, middle of the implementation, I faced this error. I rolled back my some code and altered the method of adding the above column as:

var temp=Ext.create('Ext.grid.TemplateColumn',{
....
});

and removed id attribute. Now, that error is gone. Hope this info will help somebody. I am sure this error comes because of some error prone code not handled by event.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top