removeEventListener not working on a button after clicking

So I have a button, that inside the listener I want to remove the current listener so the user cant click over and over, but it doesn’t remove the listener and still executes all the code within that listener. My code is below. Any help appreciated, thanks!

local listenerContinue = function(event)
buttonContinueRolled:removeEventListener(“touch”, listenerContinue)

media.playEventSound(sound_selection);

media.stopSound();

return true;
end

local function animateButtons()

buttonContinueRolled = display.newImage(“2a_button_continue.png”);
buttonContinueRolled:addEventListener(“touch”, listenerContinue );
end [import]uid: 6317 topic_id: 893 reply_id: 300893[/import]

Opened as case 146 [import]uid: 54 topic_id: 893 reply_id: 2085[/import]

We’ve got a fix coming in the next build, but note you will need to modify your code or you will not benefit from the fix.

(1) there is a difference between “local f = function(e)” and “local function f(e)”. In the former, “f” will be nil inside the function because the assignment won’t occur until the “end” of the function. Hence, the latter must be used if “f” is referred to inside the function f itself.

(2) all phases of a touch will get fired to the listener, even if removed in the “began” phase, so you should generally remove on the “ended” phase.

Here’s the corrected code:

[code]
local buttonContinueRolled

–local listenerContinue = function(event)
local function listenerContinue(event) – (1)

print("listenerContinue: " … event.phase )

if ( “ended” == event.phase ) then – (2)
print( type(listenerContinue) )
buttonContinueRolled:removeEventListener(“touch”, listenerContinue)
end

return true;
end

local function animateButtons()

print(“animateButtons”)

buttonContinueRolled = display.newImage(“2a_button_continue.png”);
buttonContinueRolled:addEventListener(“touch”, listenerContinue );
end

animateButtons()
[/code] [import]uid: 26 topic_id: 893 reply_id: 2362[/import]

Hi walter,

I see a problem with this fix. By removing the ability to predefine the function at the beginning of your script, the eventlistener function always have to be infront of everything that handles it. Sometimes that can be impossible because of LUA’s scope limitations. To be independant from the function placement, you have to predefine the function identifier. Like this:

foo = 0

foo = function(…)

end [import]uid: 5712 topic_id: 893 reply_id: 2373[/import]

Hi Mike,

The fix addresses an issue in our API. It does not affect Lua’s scoping rules.

The issue with your original code was that it does not account for lexical scoping. You can see for yourself, by comparing the results of:

local f = function()  
 print( type(f) )  
end  
  
f()  

versus

local function f()  
 print( type(f) )  
end  
  
f()  

at http://www.lua.org/cgi-bin/demo The former produces “nil” whereas the latter produces “function”. In the former, the assignment of “f” to the function chunk has not completed, so recursive references to “f” inside the chunk will be treated as global lookups, not as closure lookups (upvalues).

Section 6.2 of “Programming in Lua, 2nd edition” (http://www.lua.org/pil/6.2.html) explains the subtle issue:

"A subtle point arises in the definition of recursive local functions. The naive approach does not work here:

 local fact = function (n)  
 if n == 0 then return 1  
 else return n\*fact(n-1) -- buggy  
 end  
 end  

When Lua compiles the call fact(n-1), in the function body, the local fact is not yet defined. Therefore, that expression calls a global fact, not the local one."
[import]uid: 26 topic_id: 893 reply_id: 2375[/import]