Cant work out why I'm getting Attempt to index global '' (a nil value) error

Hi 

I’m getting the error “Attempt to index global ‘nextQ’ (a nil value)” from the following code and I’m not sure why. I cant seem to reference anything inside that function. All I need is for the button to be removed once pressed. Its not a local variable so I assumed it should work. Any ideas?

 local function nextButton() nextQ:removeSelf() nextQ = nil --destroyAll() --getNewQuiz() end nextQ = widget.newButton( { parent = sceneGroup, label = "Next -\>", onEvent = nextButton, emboss = false, -- Properties for a rounded rectangle button shape = "roundedRect", width = 100, height = 50, cornerRadius = 2, fillColor = { default={1,1,1,1}, over={1,0.1,0.3,0.4} }, strokeColor = { default={0.1,0.3,0,1}, over={0.9,0.8,1,1} }, strokeWidth = 10 } ) nextQ.x = centerX +250 nextQ.y = centerY + 45 end

I assume the error is popping up at the nextQ:removeSelf() line?  Could be the listener firing again after you removed the button but theoretically that should not happen, also your code actually works in my sim.  You could try this so it only gets picked up on one phase of the listener (change to “began” if you want it to be removed the exact time you touch it):

local function nextButton(event) if event.phase == "ended" then nextQ:removeSelf() nextQ = nil --destroyAll() --getNewQuiz() end end

phil_s

Is certainly right.  

**Update: I didn’t read Phil’s full post, so he and I have some overlap**

You’re passing that listener in the ‘onEvent’ field.  It will get called for a number of touch phases and you delete it right away thus breaking the widget code.  

If you do this:

local function nextButton() print("Called nextButton() @ ", system.getTimer()) nextQ:removeSelf() nextQ = nil --destroyAll() --getNewQuiz() end

I guarantee you’ll see a bunch of calls to the function:

Called nextButton() @ time 1 Called nextButton() @ time 2 ...

You should really add an event field to your function and only delete on ‘ended’.

See docs: https://docs.coronalabs.com/daily/api/library/widget/newButton.html

Probably something like this (I don’t use widgets so I may be wrong):

local function nextButton(event) if( event.phase == "ended" ) then display.remove( nextQ ) nextQ = nil --destroyAll() --getNewQuiz() end end

Thanks guys, great help!  :slight_smile:

I assume the error is popping up at the nextQ:removeSelf() line?  Could be the listener firing again after you removed the button but theoretically that should not happen, also your code actually works in my sim.  You could try this so it only gets picked up on one phase of the listener (change to “began” if you want it to be removed the exact time you touch it):

local function nextButton(event) if event.phase == "ended" then nextQ:removeSelf() nextQ = nil --destroyAll() --getNewQuiz() end end

phil_s

Is certainly right.  

**Update: I didn’t read Phil’s full post, so he and I have some overlap**

You’re passing that listener in the ‘onEvent’ field.  It will get called for a number of touch phases and you delete it right away thus breaking the widget code.  

If you do this:

local function nextButton() print("Called nextButton() @ ", system.getTimer()) nextQ:removeSelf() nextQ = nil --destroyAll() --getNewQuiz() end

I guarantee you’ll see a bunch of calls to the function:

Called nextButton() @ time 1 Called nextButton() @ time 2 ...

You should really add an event field to your function and only delete on ‘ended’.

See docs: https://docs.coronalabs.com/daily/api/library/widget/newButton.html

Probably something like this (I don’t use widgets so I may be wrong):

local function nextButton(event) if( event.phase == "ended" ) then display.remove( nextQ ) nextQ = nil --destroyAll() --getNewQuiz() end end

Thanks guys, great help!  :slight_smile: