Transfer data between scenes

Hi

In my App I’d like to transfer data between different two scenes. I also use SQLite to populate the screen in one scene. This then generates different buttons. My goal is to send the button Id to the next scene, where I then generate the level (again from an SQLite table).

I have read this article(http://www.coronalabs.com/blog/2012/08/07/managing-state-between-scenes/), and many others, but just couldn’t find a solution.

Could someone please help?

My code in Scene1:

local function onSceneTouch( self, event ) if event.phase == "began" then storyboard.gotoScene( "scene2", "fade", 400) return true end end -- Called when the scene's view does not exist: function scene:createScene( event ) local screenGroup = self.view --BEGIN SQLITE require "sqlite3" --Open data.db. If the file doesn't exist it will be created local path = system.pathForFile("data.db", system.DocumentsDirectory) db = sqlite3.open( path ) --Handle the applicationExit event to close the db local function onSystemEvent( event ) if( event.type == "applicationExit" ) then db:close() end end --setup the system listener to catch applicationExit Runtime:addEventListener( "system", onSystemEvent ) --END SQLITE end -- Called immediately after scene has moved onscreen: function scene:enterScene( event ) local screenGroup = self.view function newButton ( routeId, routeName, status ) local self = {} self.routeId = routeId self.routeName = routeName self.status = status function self:createButton() local pos = "images/pos.png" local neg = "images/neg.png" if (self.status == 1) then image = display.newImage( pos ) else image = display.newImage( neg ) end image.x = 30 + (self.routeId \* 90) image.y = 250 --+ (self.routeId \* 50) screenGroup:insert( image ) image.touch = onSceneTouch image:addEventListener( "touch", image ) end return self end local buttons = {} --print all the table contents for row in db:nrows("SELECT \* FROM main") do local routeId = row.route\_id local routeName = row.route\_name local difficulty = row.difficulty local status = row.climbed\_status local t = display.newText(routeName, 0 + (90 \* row.route\_id), 310, native.systemFont, 20) t:setTextColor(255,255,255) screenGroup:insert( t ) local i = newButton( routeId, routeName, status ) i:createButton() buttons[routeId] = { routeId = routeId } end end

And then in Scene2 I have:

 local routeId = event.routeId

Is there somewhere in the code snippet that you think you are telling it to pass data to another scene?  I just ask because I don’t see anything.

Really you could just do

[lua]

  storyboard.state = {}

  storyboard.state.routeId = self.routeId

[/lua]

  in your onSceneTouch.  just make sure it’s done before you call the gotoScene.

In your other scene you can then just do

[lua]

local routeId = storyboard.state.routeid.

[/lua]

this might help:

http://forums.coronalabs.com/topic/36474-how-to-access-database-record-selected-in-one-scene-in-new-scene/

thank you for all the effort. Have tryied the first solution but it didn’t work. on the next scene route_id was null. I probably did something wrong in the implementation. 

local storyboard = require( "storyboard" ) local scene = storyboard.newScene() storyboard.state = {} local mydata = require("mydata") local text1, image, route local function onSceneTouch( self, event ) if event.phase == "began" then storyboard.state.routeId = self.routeId storyboard.gotoScene( "scene3", "fade", 400) return true end end

but how do I know which button was pressed?

The variable that was passed was routeId, not route_id.  Also, isn’t that how you are identifying the button that is pushed? 

Oh, I have misspelled it a bit in the previous post. But in the code is OK. Its kinda difficult for me to explain, since I’m new to programing. I have also tryed this - print(self.routedId) as you can see bellow. But this has also no value. How should I call the routeId?

local function onSceneTouch( self, event ) if event.phase == "began" then print(self.routeId) -- prints out Nil storyboard.state.routeId = self.routeId storyboard.gotoScene( "scene3", "fade", 400) return true end end

It’s kind of hard to follow what you are expecting to happen but the problem is in this block of code I believe.  

[lua]

function newButton ( routeId, routeName, status )
        local self = {}
        
        self.routeId = routeId
        self.routeName = routeName
        self.status = status
                
        function self:createButton()
            local pos = “images/pos.png”
            local neg = “images/neg.png”
                        
            if (self.status == 1) then
                image = display.newImage( pos )
            else
                image = display.newImage( neg )
            end
        
            image.x = 30 + (self.routeId * 90)
            image.y = 250 --+ (self.routeId * 50)
            screenGroup:insert( image )
            image.touch = onSceneTouch
            image:addEventListener( “touch”, image )
            
            
        end
            
        return self

    end    

[/lua]

I could be wrong as I don’t use table listeners often but you are assigning your routeId to a self table you created.  The problem is that the touch event is assigned to the image object.  When the touch event fires off the ‘self’ in that event refers to the image object which has no .routeId property.  When creating the image object try assigning the routeId to it.  I think they will get you where to be.

On a side note in the code above I wouldn’t have created my own variable called self.   It can cause confusion and hard to track down issues as all that code is in your scene:enterScene event which already has a variable called self.  

Thanks Budershank. 

This post also helped me. 

http://forums.coronalabs.com/topic/34651-passing-a-parameter-from-an-event-listener-to-a-function-help/

Otherwise your solution works like a charm… :slight_smile:

Is there somewhere in the code snippet that you think you are telling it to pass data to another scene?  I just ask because I don’t see anything.

Really you could just do

[lua]

  storyboard.state = {}

  storyboard.state.routeId = self.routeId

[/lua]

  in your onSceneTouch.  just make sure it’s done before you call the gotoScene.

In your other scene you can then just do

[lua]

local routeId = storyboard.state.routeid.

[/lua]

this might help:

http://forums.coronalabs.com/topic/36474-how-to-access-database-record-selected-in-one-scene-in-new-scene/

thank you for all the effort. Have tryied the first solution but it didn’t work. on the next scene route_id was null. I probably did something wrong in the implementation. 

local storyboard = require( "storyboard" ) local scene = storyboard.newScene() storyboard.state = {} local mydata = require("mydata") local text1, image, route local function onSceneTouch( self, event ) if event.phase == "began" then storyboard.state.routeId = self.routeId storyboard.gotoScene( "scene3", "fade", 400) return true end end

but how do I know which button was pressed?

The variable that was passed was routeId, not route_id.  Also, isn’t that how you are identifying the button that is pushed? 

Oh, I have misspelled it a bit in the previous post. But in the code is OK. Its kinda difficult for me to explain, since I’m new to programing. I have also tryed this - print(self.routedId) as you can see bellow. But this has also no value. How should I call the routeId?

local function onSceneTouch( self, event ) if event.phase == "began" then print(self.routeId) -- prints out Nil storyboard.state.routeId = self.routeId storyboard.gotoScene( "scene3", "fade", 400) return true end end

It’s kind of hard to follow what you are expecting to happen but the problem is in this block of code I believe.  

[lua]

function newButton ( routeId, routeName, status )
        local self = {}
        
        self.routeId = routeId
        self.routeName = routeName
        self.status = status
                
        function self:createButton()
            local pos = “images/pos.png”
            local neg = “images/neg.png”
                        
            if (self.status == 1) then
                image = display.newImage( pos )
            else
                image = display.newImage( neg )
            end
        
            image.x = 30 + (self.routeId * 90)
            image.y = 250 --+ (self.routeId * 50)
            screenGroup:insert( image )
            image.touch = onSceneTouch
            image:addEventListener( “touch”, image )
            
            
        end
            
        return self

    end    

[/lua]

I could be wrong as I don’t use table listeners often but you are assigning your routeId to a self table you created.  The problem is that the touch event is assigned to the image object.  When the touch event fires off the ‘self’ in that event refers to the image object which has no .routeId property.  When creating the image object try assigning the routeId to it.  I think they will get you where to be.

On a side note in the code above I wouldn’t have created my own variable called self.   It can cause confusion and hard to track down issues as all that code is in your scene:enterScene event which already has a variable called self.  

Thanks Budershank. 

This post also helped me. 

http://forums.coronalabs.com/topic/34651-passing-a-parameter-from-an-event-listener-to-a-function-help/

Otherwise your solution works like a charm… :slight_smile: