Functions from external module -- correct way to show in sceneGroup?

Okay, I’ve been struggling with what I’m going to bet is a relatively easy/common problem – I’ve searched the forums and docs but can’t seem to find the answer that fixes my issue.

I’m building a business app that will eventually be (hopefully) opening newWebPopups for each of the links to externally hosted pdf documents I’m linking to. There are many of these, broken down by categories of products. Each product has at least 4 pdf documents I’ll be linking to, and there are 70+ products.

At this point, what I think I would like to achieve is to have an external module with a function I can call in each product scene so that I only have to set a local variable (linkA, linkB, linkC, etc.) with the correct parameters (title, name, url), and add it to the sceneGroup correctly, so that they will be removed upon transitioning back to the parent scene, or any other scene. If this is perhaps not the most awesome way to go about doing this, any advice would be welcome, as well.

Here’s what I’ve got:

links.lua

[lua]

local link = {}

local link_mt = { __index = link }   – metatable


– PRIVATE FUNCTIONS


– put them here if you can think of them


– PUBLIC FUNCTIONS


function link.new( title, name, url )   – constructor (these are the variables to use when creating a new link)

local newLink = {

title = title,

name = name,

target = url

}

local mainFont = “Gotham-Black.ttf”

local otherFont = “Gotham-Book.ttf”

function link:createNew()

local text = display.newText( self.title, display.contentCenterX, display.contentCenterY, otherFont, 16 )

end

function link:makeTouchable()

newLink:addEventListener(“touch”, linkTouch) --<— to do: make this work (to call newWebPopup)

end

return setmetatable( newLink, link_mt )

end


function link:printInfo()

print( self.name … " links to " … self.target )

print( self.name … " will be displayed in text as " … self.title )

end

return link

[/lua]

And here’s the only way I’ve been able to make it appear in the product module thus far:

fss45dc.lua

[lua]

local utils = require( “utils” )

local ff = require( “func” )

local link = require( “links” )

local widget = require( “widget” )

local composer = require( “composer” )

local scene = composer.newScene()

composer.setVariable( “parentScene”, “ic”)

function scene:create( event )

local sceneGroup = self.view

– create background group

local bg = utils.newBgGroup( 50, 50 )

local vfLogo = utils.newLogo( 50, 50 )

local goArrow = utils.newGoArrow( 50, 50 )

– create stuff here

local docGroup = display.newGroup()

– create some text

local mainFont = “Gotham-Black.ttf”

local otherFont = “Gotham-Book.ttf”

local title = display.newText( “FSS 45DC™ Documents”, display.contentCenterX, 110, mainFont, 24 )

local link1 = link.new( “FSS 45DC™ Datasheet”, “tdsUrl”, “http://versaflex.com/f/ds-VFfss45dc.pdf”)

link1:createNew() --<— this isn’t a part of the sceneGroup, so can’t be destroyed :\

link1:printInfo()

– create groups & other stuff here

local docGroup = display.newGroup()

docGroup.x = contentCenterX

docGroup.y = contentCenterY

docGroup:insert( title )

– Add stuff to scene here

sceneGroup:insert( bg )

sceneGroup:insert( vfLogo )

sceneGroup:insert( goArrow )

sceneGroup:insert( docGroup )

–sceneGroup:insert( link1 )  <----- this throws an error

– Add Event Listeners here

vfLogo:addEventListener(“touch”, logoTouch)

goArrow:addEventListener(“touch”, goBack)

end

– rest of scene:functions / addEventListeners removed for brevity

[/lua]

So, obviously I’m missing something critical here ( *cough* knowledge ), and so I’m wondering how can I achieve the goal of getting this working smoothly and efficiently? 

Thanks for any advice.

Hi @jason745,

I think you’re making it a bit more complicated than it needs to be. :slight_smile: I don’t think any of the metatable stuff is needed in your case.

I’d just make the “links.lua” module very simple, with one function inside, “new()”, create the link itself, then return it to the calling module/scene.

Something like this, at its most simple form:

[lua]

– links.lua

local M = {}

function M.new( title, name, url )

    local link = display.newText( )  – Create link object

    

    return link

end

return M

[/lua]

Then, back in the main scene…

[lua]

local links = require( “links” )

local link1 = links.new( “FSS 45DC™ Datasheet”, “tdsUrl”, “http://versaflex.com/f/ds-VFfss45dc.pdf” )

– Now you have this local object to use, i.e. place in the scene, position it, add a touch listener to it, etc.

[/lua]

Hope this helps gets you started!

Brent

Hi Brent, 

 

Thanks so much for the reply. That does seem simpler, but now when using (basically) exactly what you have posted above, I’m getting an error "bad argument #1 to ‘newText’ (string expected, got no value). This is perplexing since it would seem the “FSS 45DC”, “tdsUrl”, “http://blahblah” are all pretty obviously strings, right? And they’re passed in the local link1 variable, just as shown above, so am I still missing something? 

 

Thanks again.

Hi Jason,

I’d have to see the exact code you’re using for the “newText()” call. Most likely it’s just a simple syntax thing.

Brent

Hi Brent,

I used _exactly_ the code you posted above, which seems to throw that error. I also thought it might be a syntax thing, which often plagues me, but I’ve not been able to pin down what’s wrong. 

Additionally, what I was really hoping for was something that would allow me to say, “Here’s one of these objects, and here are its properties / parameters. Make it so it (and any others I designate thusly) can do x/y/z based on the parameters given.” Perhaps it would more resemble a class of object, really. But it would seem to me like a more efficient / elegant solution would be to have most of the heavy lifting done by the links module, rather than having to write out similar functions for each of the links in each product scene?

Thanks again for any advice.

Hi Jason,

Sorry, I presumed too much in my example code… the suggestion was to take the arguments passed in to the “M.new()” function (title, name, url) and use those to create a text object, then assign it a touch/tap listener to open a web page or whatever. I’m not sure exactly how you want to do those tasks, so I left it open-ended for your flexibility.

Brent

Hi @jason745,

I think you’re making it a bit more complicated than it needs to be. :slight_smile: I don’t think any of the metatable stuff is needed in your case.

I’d just make the “links.lua” module very simple, with one function inside, “new()”, create the link itself, then return it to the calling module/scene.

Something like this, at its most simple form:

[lua]

– links.lua

local M = {}

function M.new( title, name, url )

    local link = display.newText( )  – Create link object

    

    return link

end

return M

[/lua]

Then, back in the main scene…

[lua]

local links = require( “links” )

local link1 = links.new( “FSS 45DC™ Datasheet”, “tdsUrl”, “http://versaflex.com/f/ds-VFfss45dc.pdf” )

– Now you have this local object to use, i.e. place in the scene, position it, add a touch listener to it, etc.

[/lua]

Hope this helps gets you started!

Brent

Hi Brent, 

 

Thanks so much for the reply. That does seem simpler, but now when using (basically) exactly what you have posted above, I’m getting an error "bad argument #1 to ‘newText’ (string expected, got no value). This is perplexing since it would seem the “FSS 45DC”, “tdsUrl”, “http://blahblah” are all pretty obviously strings, right? And they’re passed in the local link1 variable, just as shown above, so am I still missing something? 

 

Thanks again.

Hi Jason,

I’d have to see the exact code you’re using for the “newText()” call. Most likely it’s just a simple syntax thing.

Brent

Hi Brent,

I used _exactly_ the code you posted above, which seems to throw that error. I also thought it might be a syntax thing, which often plagues me, but I’ve not been able to pin down what’s wrong. 

Additionally, what I was really hoping for was something that would allow me to say, “Here’s one of these objects, and here are its properties / parameters. Make it so it (and any others I designate thusly) can do x/y/z based on the parameters given.” Perhaps it would more resemble a class of object, really. But it would seem to me like a more efficient / elegant solution would be to have most of the heavy lifting done by the links module, rather than having to write out similar functions for each of the links in each product scene?

Thanks again for any advice.

Hi Jason,

Sorry, I presumed too much in my example code… the suggestion was to take the arguments passed in to the “M.new()” function (title, name, url) and use those to create a text object, then assign it a touch/tap listener to open a web page or whatever. I’m not sure exactly how you want to do those tasks, so I left it open-ended for your flexibility.

Brent