PDA

View Full Version : [FIXED-407/408][3.1] fn.task is undefined error message in createBuffered



calinseciu
19 Dec 2009, 2:30 AM
I have some issues with buffered events as I get the "fn.task is undefined" error message in createBuffered, with code that worked flawlessly before.

I can't post any code here because I don't know what could be causing this.
Please help.

calinseciu
19 Dec 2009, 7:11 AM
I have some more info on this. Looks like the problem could be caused by a PropertyGrid which I have in the code.
After property change, I have an event which runs a function. The error is related to the blur event of the input field of the property which was edited.

MartiCode
20 Dec 2009, 2:53 AM
From what I have seen the problem shows up when buffered events are involved, and either the listener was not removed properly or set at specific places. For ex. I got one of those fixed by switching the buffered listener set by a component from the initComponent method to the end of the onRender one.

evant
20 Dec 2009, 9:39 PM
Can anyone post a reproducible test case?

calinseciu
21 Dec 2009, 7:15 AM
I am using a custom PropertyGrid which extends an EditorGridPanel: Ext.ux.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {...config...});

After a property changes, I am firing an event "propertychange".

This is what console.log in firebug shows inside the createBuffered(h, o, fn) function:
h = h(e)
o = Object buffer=10
fn = onBlur : function(){ (aprox line in ext-all-debug.js: 35377) this.beforeBlur(); .....
e (blur) = bubbles - false currentTarget - input#ext-comp-1013.x-form-text [InputValue] ...

input#ext-comp-1013 is the Textfield that appears on edit property.

Is this of any help ?
Thanks

jdent
22 Dec 2009, 11:57 AM
This is a major issue for us. It looks like there are individual references to tasks being applied to a prototype function.

In my example I have two text fields and remove one of them with the click of a button. This will cause an error in the "createBuffered" function contained in Ext.EventManger when you try to type in the remaining text field. Since the "task" is applied to the prototype, removing one field and its listeners will also remove the existing buffered and/or delayed tasks for the still existing fields.
Note: this will be an issue if there are delayed or buffered listeners being applied, in this case the grow will apply a keyup buffered listener.
Here is the code for my example:


//pass
// container - container to house main panel
testBug = function(container){
var fld= new Ext.form.TextField({
fieldLabel: 'Field 1 Ext',
grow: true
});
var fld2 = new Ext.form.TextField({
fieldLabel: 'Field 2 Ext',
grow: true
});
var button = new Ext.Button({
text: 'Remove Field 2'
});
var panel = new Ext.FormPanel({
title: 'Bug Test',
items: [fld,fld2,button]
});
button.addListener('click',function(){
panel.remove(fld2);
});
container.add(panel);
container.doLayout();
container.setActiveTab(panel);
}

miti
22 Dec 2009, 3:38 PM
Got a similar problem. I have an editor grid and when I finish editing a cell and click on anywhere else in the screen, the editor lost focus and I got the fn.task undefined. It worked great before on 3.0

Condor
22 Dec 2009, 11:08 PM
Yes, createBuffered (and createDelayed) need to create a 'task' (or 'tasks') property for every listener instead of one for each fn.

Something like:

function createBuffered(h, l, o, fn, scope){
l.task = new EXTUTIL.DelayedTask();
return function(){
l.task.delay(o.buffer, h, scope, TOARRAY(arguments));
};
};
function createDelayed(h, l, o, fn, scope){
return function(){
var task = new EXTUTIL.DelayedTask();
if(!l.tasks) {
l.tasks = [];
}
l.tasks.push(task);
task.delay(o.delay || 10, h, scope, TOARRAY(arguments));
};
};
...
createListener: function(fn, scope, o){
o = o || {}, scope = scope || this.obj;
var l = {
fn: fn,
scope: scope,
options: o
}, h = fn;
if(o.target){
h = createTargeted(h, o, scope);
}
if(o.delay){
h = createDelayed(h, l, o, fn, scope);
}
if(o.single){
h = createSingle(h, this, fn, scope);
}
if(o.buffer){
h = createBuffered(h, l, o, fn, scope);
}
l.fireFn = h;
return l;
},
removeListener : function(fn, scope){
var index,
l,
k,
me = this,
ret = FALSE;
if((index = me.findListener(fn, scope)) != -1){
if (me.firing) {
me.listeners = me.listeners.slice(0);
}
l = me.listeners[index]/*.fn*/;
if(l.task) {
l.task.cancel();
delete l.task;
}
k = l.tasks && l.tasks.length;
if(k) {
while(k--) {
l.tasks[k].cancel();
}
delete l.tasks;
}
me.listeners.splice(index, 1);
ret = TRUE;
}
return ret;
},

(same applies to DOM listeners, but that will be a bit harder to implement)

Jamie Avins
6 Jan 2010, 6:31 PM
Fixed in ext-core svn 125 and 126 (EventManager and Observable) references.

vladcd
18 Jan 2010, 12:53 AM
Hi,

I had the bug described here in ext 3.1.0
Now I tried ext 3.1.1 beta to see if the problem has been solved. Unfortunately, the bug is the same, only the error message has changed (fn[0].tasks is undefined).

It breaks at: ext-all-debug.js, line 2936 (corresponds to EventManager.js, line 379). If you can't reproduce it with the test case previously provided in this thread (by someone else), please tell me and I will try to make one in the shortest amount of time.

Thank you very much,
Vlad

vladcd
18 Jan 2010, 1:56 AM
Sorry about the previous report.

It seems like the problem was on my side.

There was somwhere a construction like:


this.on('click', this.onClick, this);

but with the 'small' detail that this.onClick was undefined; This caused the error I was talking about earlier.

However, what do you think about inserting an ' proof' check(method removeAll in EventManager.js):


...
for (i = 0, len = f.length; i < len; i++) {
fn = f[i][0];
if(Ext.isDefined(fn)){
.... // the rest of the method
}
}



Thanks and sorry for the bother, if any
Vlad