event.params always nil when calling gotoScene from within scene

I’m trying to reload composer scenes. What’s happening is that the user can delete UI elements which results in the layout needing to be redrawn. Sometimes there are parameters to be preserved between these reloads - for instance the scene to return to when done, or filters to apply to the layout.

The issue I’m having is that after calling:

-- inside scenes.myscene:show function someUIWhichModifiesLayout:tap() ... change data composer.removeScene("scenes.myscene") composer.gotoScene("scenes.myscene",{params=\_.clone(params,false)}) end)

The event.params field will always be nil. Am I doing something wrong or is there an issue with composer? I’m tempted to try introducing an intermediary router scene to see if that resolves the issue - something which just calls gotoScene with arguments and parameters specified by the caller to see if that works…

For the time being the following works:

New scene, scenes.reload:

local composer=require "composer" local scene=composer.newScene() local \_=require "util.moses" setfenv(1, scene) function scene:show(event) if event.phase~="will" then return end composer.gotoScene(event.params.scene,{params=\_.clone(event.params.params,false)}) end scene:addEventListener("show") return scene

and the new call is:

composer.removeScene("scenes.myscene") composer.gotoScene("scenes.reload",{params={scene="scenes.myscene",params={filters=\_.clone(filters,false)}}})

the “cutscene” approach is the typical solution.

note that your removeScene() call isn’t actually doing anything - composer (and storyboard) can’t remove the current scene.

“why” your original code fails - because your call to gotoScene() is trying to “go to” the current scene.  Composer recognizes this, and knows that it can’t literally do that, so instead calls an internal reloadScene method.  unfortunately, reloadScene doesn’t respect params in the event, so they’re lost, it does NOT function exactly the same as a true gotoScene(someOTHERscene).  this “weirdness” has been present in storyboard for a long time, and composer inherited it.

Thanks for the explanation! It’s good to know what the reasons under the hood are.

For the time being the following works:

New scene, scenes.reload:

local composer=require "composer" local scene=composer.newScene() local \_=require "util.moses" setfenv(1, scene) function scene:show(event) if event.phase~="will" then return end composer.gotoScene(event.params.scene,{params=\_.clone(event.params.params,false)}) end scene:addEventListener("show") return scene

and the new call is:

composer.removeScene("scenes.myscene") composer.gotoScene("scenes.reload",{params={scene="scenes.myscene",params={filters=\_.clone(filters,false)}}})

the “cutscene” approach is the typical solution.

note that your removeScene() call isn’t actually doing anything - composer (and storyboard) can’t remove the current scene.

“why” your original code fails - because your call to gotoScene() is trying to “go to” the current scene.  Composer recognizes this, and knows that it can’t literally do that, so instead calls an internal reloadScene method.  unfortunately, reloadScene doesn’t respect params in the event, so they’re lost, it does NOT function exactly the same as a true gotoScene(someOTHERscene).  this “weirdness” has been present in storyboard for a long time, and composer inherited it.

Thanks for the explanation! It’s good to know what the reasons under the hood are.