Accessing a variable in another lua file

Hi, I’m a beginner to Lua! Trying to get an app up and running really quickly.

I tried to make a sliding panel as in this example:

https://coronalabs.com/blog/2014/04/08/widgets-creating-a-sliding-panel/

And everything worked fine when it was all in one script. However, I put the following lines in another script called “createPanel.lua”: 

local widget = require("widget") local function panelTransDone( target )     --native.showAlert( "Panel", "Complete", { "Okay" } )     if ( target.completeState ) then       print( "PANEL STATE IS: "..target.completeState )     end   end panel = widget.newPanel{   location = "left",   onComplete = panelTransDone,   width = display.contentWidth \* 0.5,   height = display.contentHeight,   speed = 250,   inEasing = easing.outBack,   outEasing = easing.outCubic } panel.background = display.newRect( 0, 0, panel.width, panel.height ) panel.background:setFillColor( 0, 0.25, 0.5 ) panel:insert( panel.background ) panel.title = display.newText( "Menu", 0, 0, native.systemFontBold, 18 ) panel.title:setFillColor( 1, 1, 1 ) panel:insert( panel.title )

And in my original script I say 

local createPanel = require("scripts.createPanel")

I get no errors, but when I call panel:show() in my original script, it doesn’t work. I know the createPanel() script is being called because I get the alert from 

native.showAlert( "Panel", "Complete", { "Okay" } )

so I’m a bit confused.

On a side note, does anybody know if there’s a better way to debug things? Should I just be printing things out to the console a lot? 

Is that all the code for createPanel.lua?

Can you also post your code where you’re trying to show the panel?

Rob

Yep! 

--Required APIs and Libraries local composer = require( "composer" ) local display = require("display") local widget = require( "widget" ) local createPanel = require( "scripts.createPanel" ) --This is where I access the other script --Create new scene object local scene = composer.newScene() -- "scene:create()" function scene:create( event )    local sceneGroup = self.view    local background = display.newRect(                       display.contentWidth/2,                       display.contentHeight/2,                       display.contentWidth,                       display.contentHeight);    background:setFillColor(225/255, 225/255, 225/255)    local function handleLeftButton( event )       if ( event.phase == "ended" ) then          panel:show() -- I try to access the panel here       end       return true    end    local function handleRightButton( event )       if ( event.phase == "ended" ) then          -- do stuff       end       return true    end    local leftButton = {       onEvent = handleLeftButton,       width = 60,       height = 34,       defaultFile = "images/ic\_menu\_black\_24px.svg",       overFile = "images/ic\_menu\_black\_24px.svg",       isBackButton = false    }    local rightButton = {       onEvent = handleRightButton,       label = "ADD",       labelColor = { default =  {0, 0, 0}, over = { 0.5, 0.5, 0.5} },       font = "ElegantLight.ttf",       isBackButton = false    }    local navBar = widget.newNavigationBar({       title = "FLARE",       backgroundColor = { 1, 1, 1 },       titleColor = {0,0,0},       font = "ElegantLight.ttf",       leftButton = leftButton,       rightButton = rightButton,       includeStatusBar = true    })   panel = createPanel.createPanel() -- panel = createPanel:createPanel() --Not sure if I'm doing this right, or if this has to be done at all since I've already "included" the other script --Everything past this point is extraneous end -- "scene:show()" function scene:show( event )    local sceneGroup = self.view    local phase = event.phase    if ( phase == "will" ) then       -- Called when the scene is still off screen (but is about to come on screen).    elseif ( phase == "did" ) then       -- Called when the scene is now on screen.       -- Insert code here to make the scene come alive.       -- Example: start timers, begin animation, play audio, etc.    end end -- "scene:hide()" function scene:hide( event )    local sceneGroup = self.view    local phase = event.phase    if ( phase == "will" ) then       -- Called when the scene is on screen (but is about to go off screen).       -- Insert code here to "pause" the scene.       -- Example: stop timers, stop animation, stop audio, etc.    elseif ( phase == "did" ) then       -- Called immediately after scene goes off screen.    end end -- "scene:destroy()" function scene:destroy( event )    local sceneGroup = self.view    -- Called prior to the removal of scene's view ("sceneGroup").    -- Insert code here to clean up the scene.    -- Example: remove display objects, save state, etc. end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) --------------------------------------------------------------------------------- return scene

Also worth noting: the console says

PANEL STATE IS: shown

whenever I click on the left button. However, the panel does not appear like it did before! Sorry for the late replies

There are a couple things going on.

First your module should return a table/object, something like this:

local widget = require("widget") local function panelTransDone( target ) --native.showAlert( "Panel", "Complete", { "Okay" } ) if ( target.completeState ) then print( "PANEL STATE IS: "..target.completeState ) end end local M = {} function M.createPanel() local panel = widget.newPanel { location = "left", onComplete = panelTransDone, width = display.contentWidth \* 0.5, height = display.contentHeight, speed = 250, inEasing = easing.outBack, outEasing = easing.outCubic } panel.background = display.newRect( 0, 0, panel.width, panel.height ) panel.background:setFillColor( 0, 0.25, 0.5 ) panel:insert( panel.background ) panel.title = display.newText( "Menu", 0, 0, native.systemFontBold, 18 ) panel.title:setFillColor( 1, 1, 1 ) panel:insert( panel.title ) return panel end return M

Then make sure to localize “panel” in your scene. Maybe put a:

local panel near the top of your scene. Right now you’re creating “panel” as a global and they are stomping on each other.

Rob

So I have createPanel returning M, as you have it , and inserted a

local panel

before any of the functions in menuScene.

However, both M and panel are nil. How do I call the createPanel() function in createPanel.lua? 

Found the error

I ended up passing the table M as you did in the previous post. However, I tried

local panel = createPanel.createPanel()

before the function definitions and it still wasn’t working. What worked was leaving panel as global inside of the function so that I had

panel = createPanel.createPanel()

inside of the function scene:create.

OR, if I wanted to keep the panel as local, I could put that line inside of the button handler, like

local function handleLeftButton( event )       if ( event.phase == "ended" ) then         local panel = createPanel.createPanel()          panel:show()       end       return true    end

I guess defining the local panel outside of the function scene:create was the problem, though I’m not sure why that wouldn’t work.

Put 

local createPanel = require("createPanel") local panel  -- don't add anything extra here.

near the top of your scene. When you’re ready to create the panel:

panel = createPanel.createPanel()

Rob

Thank you so much for helping!

Is that all the code for createPanel.lua?

Can you also post your code where you’re trying to show the panel?

Rob

Yep! 

--Required APIs and Libraries local composer = require( "composer" ) local display = require("display") local widget = require( "widget" ) local createPanel = require( "scripts.createPanel" ) --This is where I access the other script --Create new scene object local scene = composer.newScene() -- "scene:create()" function scene:create( event )    local sceneGroup = self.view    local background = display.newRect(                       display.contentWidth/2,                       display.contentHeight/2,                       display.contentWidth,                       display.contentHeight);    background:setFillColor(225/255, 225/255, 225/255)    local function handleLeftButton( event )       if ( event.phase == "ended" ) then          panel:show() -- I try to access the panel here       end       return true    end    local function handleRightButton( event )       if ( event.phase == "ended" ) then          -- do stuff       end       return true    end    local leftButton = {       onEvent = handleLeftButton,       width = 60,       height = 34,       defaultFile = "images/ic\_menu\_black\_24px.svg",       overFile = "images/ic\_menu\_black\_24px.svg",       isBackButton = false    }    local rightButton = {       onEvent = handleRightButton,       label = "ADD",       labelColor = { default =  {0, 0, 0}, over = { 0.5, 0.5, 0.5} },       font = "ElegantLight.ttf",       isBackButton = false    }    local navBar = widget.newNavigationBar({       title = "FLARE",       backgroundColor = { 1, 1, 1 },       titleColor = {0,0,0},       font = "ElegantLight.ttf",       leftButton = leftButton,       rightButton = rightButton,       includeStatusBar = true    })   panel = createPanel.createPanel() -- panel = createPanel:createPanel() --Not sure if I'm doing this right, or if this has to be done at all since I've already "included" the other script --Everything past this point is extraneous end -- "scene:show()" function scene:show( event )    local sceneGroup = self.view    local phase = event.phase    if ( phase == "will" ) then       -- Called when the scene is still off screen (but is about to come on screen).    elseif ( phase == "did" ) then       -- Called when the scene is now on screen.       -- Insert code here to make the scene come alive.       -- Example: start timers, begin animation, play audio, etc.    end end -- "scene:hide()" function scene:hide( event )    local sceneGroup = self.view    local phase = event.phase    if ( phase == "will" ) then       -- Called when the scene is on screen (but is about to go off screen).       -- Insert code here to "pause" the scene.       -- Example: stop timers, stop animation, stop audio, etc.    elseif ( phase == "did" ) then       -- Called immediately after scene goes off screen.    end end -- "scene:destroy()" function scene:destroy( event )    local sceneGroup = self.view    -- Called prior to the removal of scene's view ("sceneGroup").    -- Insert code here to clean up the scene.    -- Example: remove display objects, save state, etc. end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) --------------------------------------------------------------------------------- return scene

Also worth noting: the console says

PANEL STATE IS: shown

whenever I click on the left button. However, the panel does not appear like it did before! Sorry for the late replies

There are a couple things going on.

First your module should return a table/object, something like this:

local widget = require("widget") local function panelTransDone( target ) --native.showAlert( "Panel", "Complete", { "Okay" } ) if ( target.completeState ) then print( "PANEL STATE IS: "..target.completeState ) end end local M = {} function M.createPanel() local panel = widget.newPanel { location = "left", onComplete = panelTransDone, width = display.contentWidth \* 0.5, height = display.contentHeight, speed = 250, inEasing = easing.outBack, outEasing = easing.outCubic } panel.background = display.newRect( 0, 0, panel.width, panel.height ) panel.background:setFillColor( 0, 0.25, 0.5 ) panel:insert( panel.background ) panel.title = display.newText( "Menu", 0, 0, native.systemFontBold, 18 ) panel.title:setFillColor( 1, 1, 1 ) panel:insert( panel.title ) return panel end return M

Then make sure to localize “panel” in your scene. Maybe put a:

local panel near the top of your scene. Right now you’re creating “panel” as a global and they are stomping on each other.

Rob

So I have createPanel returning M, as you have it , and inserted a

local panel

before any of the functions in menuScene.

However, both M and panel are nil. How do I call the createPanel() function in createPanel.lua? 

Found the error

I ended up passing the table M as you did in the previous post. However, I tried

local panel = createPanel.createPanel()

before the function definitions and it still wasn’t working. What worked was leaving panel as global inside of the function so that I had

panel = createPanel.createPanel()

inside of the function scene:create.

OR, if I wanted to keep the panel as local, I could put that line inside of the button handler, like

local function handleLeftButton( event )       if ( event.phase == "ended" ) then         local panel = createPanel.createPanel()          panel:show()       end       return true    end

I guess defining the local panel outside of the function scene:create was the problem, though I’m not sure why that wouldn’t work.

Put 

local createPanel = require("createPanel") local panel  -- don't add anything extra here.

near the top of your scene. When you’re ready to create the panel:

panel = createPanel.createPanel()

Rob

Thank you so much for helping!