How to Access Database Record Selected in One Scene, in New Scene

I am trying to learn how to show a field of a record which was selected in scene 1, when the screen switches to field two.  I have scene 1 show a summary, and if the user would like to see the main fields, they can press a button to go to the new scene. 

So, how do I maintain the data from sqlite through to the next scene, so that I can call that sqlite tableview row selected?  I have poured over documentation and forums, and the information out there seems to be only slightly related. 

@rozan,

the issue seems to be knowing the way to get data *out* of a scene. in your higher-level “controller” you could:

place an event listener on the scene you want data *from*. inside of the scene, dispatch a custom event when selection is made. this event contains the data of interest.

pass a function callback *into* the scene you want data *from*. inside of the scene, call the function when selection is made, passing the data as a parameter.

from either method, your “controller” would save and pass the data to scene 2 when it asks for it to come on stage.

cheers,
dmc

Thanks for your reply.  I’m not quite sure how to do what you say.  Would I use an sqlite statement?  I would think that I would need to use the idx indicated by the row touch… But from there I am lost.

For instance, in scene one I display a summary…

    local details = display.newText(listRecs[idx].summary, 10, list.height - 70, display.contentWidth - 20, display.contentHeight, Helvetica, 14 )         details:setTextColor(255, 255, 255)  

I would like to display listRecs[idx].text in Scene 2,…

There are a couple of ways.

  1. Storyboard scenes can pass a table of data from storyboard.gotoScene() to the loading scene’s createScene and enterScene functions.

  2. You can store the data into a module that is loaded in each scene.  I would recommend you create a module called:

mydata.lua

that has two lines of code in it:

local M = {}

return M

then in each module where you need to share data, do:

local mydata = require(“mydata”)

and after that you can access anything you add to the mydata object in that scene.

Thanks for your replies.  Because of the size of the sqlite file, I think it is best to keep that accessible, rather than place all the rows in a table.  So, if I’m understanding correctly, Rob’s option #2 is the way to go.  And that seems like an awesomely easy solution!  So, after you open the sqlite db, do you have to put each field into mydata.lua?  My code…

local function loadData()     local sql = "select \* from News" for a in db:nrows(sql) do listRecs[#listRecs+1] = { id = a.id, date = a.date, title = a.title, summary = a.summary, text = a.text } end end

How would I get the fields/rows to the mydata.lua scene? 

I have read all the documentation on the use of require() and modules, and most of the examples have just one variable passed.  My question has to do with a large database with multiple rows and fields, and also the selected one.  Would that myadata.lua file hold the entire database and the tapped row?  How would I get all that information stored temporarily in mydata.lua, where I can access it from one scene to another?

Generally speaking, if you have lots of data but you only need a little bit of it at a time, then you should use a database like SQLite.  If you need all of your data frequently, then an in-memory table makes more sense.  Keep in mind that you are limited in memory so really large data tables in memory may create performance problems and you may be relegated having to use a database anyway.

I’m using sqlite, so after the database is open, and all of it’s in tableview in a scrolling list.  When one item is selected from the table, I want that row to open in a new scene.  Does the data need to come from tableview now, or the sqlite?  How, do I get that appropriate selection and related records into the mydata.lua that you described?  That’s because after I go to the new scene, and show that full tapped record, I would like to have a forward button which shows the next record, and a back button, which shows the record preceding the selected one.  Thanks for your help!

hi Rozan,

Rob’s suggestion is essentially a way to create a global data structure for your application which can be accessed by any other module/location in your app. even though there is only one variable returned, if that variable is a table then you can put as much as you want into it.

so, starting with the flow from scene one, you could use the structure to store just the index of the row, or store just the text to display in scene two, or whatever you want:

eg, pick one of the following:

mydata.selected\_index = 45 mydata.text = "this is the text of my record" mydata.record = \<the record from sql query\>

then, in scene 2, use use that value as needed. in the last two cases, there’s nothing to do except to display the data. in the first case (with index), you would run another SQL query to find the full record.

local sql = "select \* from News where idx = " .. mydata.selected\_index

again, you can structure it as you wish. it just depends on the data you want to pass between your scenes.

also, there’s an easier way to create a global variable to use for data passing, and you don’t even need to create a module file for it. this can be accomplished with the following line located in your main:

\_G.mydata = {}

eg, pick one of the following:
 

mydata.selected_index = 45 mydata.text = “this is the text of my record” mydata.record = <the record from sql query>

then, in scene 2, use use that value as needed. in the last two cases, there’s nothing to do except to display the data. in the first case (with index), you would run another SQL query to find the full record.

I would probably choose the first option, but that’s because I don’t understand the second and third…  For mydata.text how would you delineate the fields in the record?  I am probably missing something really basic.  I would think that you could indicate that you want to pull the selected_index from the sqlite db, but then there would be some way to identify the field to print ( which is what I think you are doing in the second line).  Regarding the third option, can any sqlite query on my open database be run and assigned to mydata.record? Or is mydata.record more a command?  I’m still trying to wrap my head around items that are on the left side of the ='s sign.  

you’ve only given a code example which uses the ‘summary’ element:

local details = display.newText(listRecs[idx].summary, 10, list.height - 70, display.contentWidth - 20, display.contentHeight, Helvetica, 14 )

since that was the only data you’ve actually shown to use, option 2 was supposed to be an example of saving that part of your data:

mydata.summary = listRecs[idx].summary

of course you could save more elements from the record if you’d like in that manner.

mydata.summary = listRecs[idx].summary mydata.date = listRecs[idx].date mydata.title = listRecs[idx].title

–== sqlite records

not having used sqlite myself for data storage, i figured that it would give back a list of table structures for each record. this is indicated in your code by the variable ‘a’:

local function loadData() local sql = "select \* from News" for a in db:nrows(sql) do listRecs[#listRecs+1] = { id = a.id, date = a.date, title = a.title, summary = a.summary, text = a.text } end end

since ‘a’ is *already* a Lua table, you ought to be able to simplify the above by just saving ‘a’ instead of creating a new table:

local function loadData() local sql = "select \* from News" for a in db:nrows(sql) do listRecs[#listRecs+1] = a end end

so option three is related to that, i.e., just saving the record (Lua table) from the results:

mydata.record = listRecs[idx\_of\_tapped\_row]

remember that the intent of ‘mydata’ is to share from scene one what you need in scene two. if that’s just one element of a row, like ‘summary’, then you could just save that (option 2). or, if you need the whole record, you can either save the table (option 3), or save the index of the row and perform a search in scene 2 using the row index to get the row (option 1).

again, the choice is yours depending on how you want to structure your code.

cheers,
dmc

@rozan,

the issue seems to be knowing the way to get data *out* of a scene. in your higher-level “controller” you could:

place an event listener on the scene you want data *from*. inside of the scene, dispatch a custom event when selection is made. this event contains the data of interest.

pass a function callback *into* the scene you want data *from*. inside of the scene, call the function when selection is made, passing the data as a parameter.

from either method, your “controller” would save and pass the data to scene 2 when it asks for it to come on stage.

cheers,
dmc

Thanks for your reply.  I’m not quite sure how to do what you say.  Would I use an sqlite statement?  I would think that I would need to use the idx indicated by the row touch… But from there I am lost.

For instance, in scene one I display a summary…

&nbsp;&nbsp;&nbsp; local details = display.newText(listRecs[idx].summary, 10, list.height - 70, display.contentWidth - 20, display.contentHeight, Helvetica, 14 ) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; details:setTextColor(255, 255, 255) &nbsp;

I would like to display listRecs[idx].text in Scene 2,…

There are a couple of ways.

  1. Storyboard scenes can pass a table of data from storyboard.gotoScene() to the loading scene’s createScene and enterScene functions.

  2. You can store the data into a module that is loaded in each scene.  I would recommend you create a module called:

mydata.lua

that has two lines of code in it:

local M = {}

return M

then in each module where you need to share data, do:

local mydata = require(“mydata”)

and after that you can access anything you add to the mydata object in that scene.

Thanks for your replies.  Because of the size of the sqlite file, I think it is best to keep that accessible, rather than place all the rows in a table.  So, if I’m understanding correctly, Rob’s option #2 is the way to go.  And that seems like an awesomely easy solution!  So, after you open the sqlite db, do you have to put each field into mydata.lua?  My code…

local function loadData() &nbsp;&nbsp;&nbsp; local sql = "select \* from News" for a in db:nrows(sql) do listRecs[#listRecs+1] = { id = a.id, date = a.date, title = a.title, summary = a.summary, text = a.text } end end

How would I get the fields/rows to the mydata.lua scene? 

I have read all the documentation on the use of require() and modules, and most of the examples have just one variable passed.  My question has to do with a large database with multiple rows and fields, and also the selected one.  Would that myadata.lua file hold the entire database and the tapped row?  How would I get all that information stored temporarily in mydata.lua, where I can access it from one scene to another?

Generally speaking, if you have lots of data but you only need a little bit of it at a time, then you should use a database like SQLite.  If you need all of your data frequently, then an in-memory table makes more sense.  Keep in mind that you are limited in memory so really large data tables in memory may create performance problems and you may be relegated having to use a database anyway.

I’m using sqlite, so after the database is open, and all of it’s in tableview in a scrolling list.  When one item is selected from the table, I want that row to open in a new scene.  Does the data need to come from tableview now, or the sqlite?  How, do I get that appropriate selection and related records into the mydata.lua that you described?  That’s because after I go to the new scene, and show that full tapped record, I would like to have a forward button which shows the next record, and a back button, which shows the record preceding the selected one.  Thanks for your help!