How can I manage variable outside of a function?

 local function showPhoto( event ) if ( event.isError ) then print( "Network error - download failed: ", event.response ) elseif ( event.phase == "ended" ) then profilePhoto = display.newImage( event.response.filename, event.response.baseDirectory) profilePhoto.width, profilePhoto.height = common.fullw, 180 profilePhoto.alpha = 0 profilePhoto.anchorX = 0 profilePhoto.anchorY = 0 profilePhoto.x = 0 profilePhoto.y = 0 transition.to( profilePhoto, { time=500, delay=2000, alpha=1.0 } ) scrollView:insert( profilePhoto ) end end network.download( "http://127.0.0.1/image/" .. settingJson.image, "GET", showPhoto, "profile.png", system.TemporaryDirectory)

How can I manage a profilePhoto variable outside of a function? How can I get the value of a variable from a specified function?

You would either have to declare the variable before the function or return the variable from the function.

Here’s the same in pseudo-code:

 

-- #1: declare first local profilePhoto local function showPhoto() profilePhoto = display.newImage( event.response.filename, event.response.baseDirectory) end showPhoto() -- #2: return the variable local function showPhoto() local profilePhoto = display.newImage( event.response.filename, event.response.baseDirectory) return profilePhoto end local profilePhoto = showPhoto()

Thanks for the reply. However, I am unable to implement your method with network.download. What could be the problem?

local profilePhoto   local function showPhoto( event ) local function Listener ( event )  if ( event.isError ) then print( "Network error - download failed: ", event.response ) elseif ( event.phase == "ended" ) then profilePhoto = display.newImage( event.response.filename, event.response.baseDirectory)  return profilePhoto end end  network.download( url, "GET", Listener, "profile.png", system.TemporaryDirectory) end   showPhoto ()   profilePhoto.width, profilePhoto.height = common.fullw, 180

Tried. However, it also did not work

Well, that’s because you don’t do what I suggested. :slight_smile:

Using the code that you posted in its entirety:
 

-- #1: declare first local profilePhoto local function showPhoto( event ) if ( event.isError ) then print( "Network error - download failed: ", event.response ) elseif ( event.phase == "ended" ) then profilePhoto = display.newImage( event.response.filename, event.response.baseDirectory) profilePhoto.width, profilePhoto.height = common.fullw, 180 profilePhoto.alpha = 0 profilePhoto.anchorX = 0 profilePhoto.anchorY = 0 profilePhoto.x = 0 profilePhoto.y = 0 transition.to( profilePhoto, { time=500, delay=2000, alpha=1.0 } ) scrollView:insert( profilePhoto ) end end network.download( "http://127.0.0.1/image/" .. settingJson.image, "GET", showPhoto, "profile.png", system.TemporaryDirectory) -- removed #2 to keep it shorter

I would recommend that you go read through http://lua-users.org/wiki/FunctionsTutorial. It’ll probably help you out a lot.

Oh, also, when you later edit your posts (and their code contents), you’ll most likely render the subsequent posts that reply to yours inaccurate. I seems to me now that my pseudo-code and I failed to convey the message, so I’d recommend again that you go through the functions tutorial that I posted earlier.

 local profilePhoto local function showPhoto( event ) if ( event.isError ) then print( "Network error - download failed: ", event.response ) elseif ( event.phase == "ended" ) then profilePhoto = display.newImage( event.response.filename, event.response.baseDirectory) end end network.download( url, "GET", showPhoto, "profile.png", system.TemporaryDirectory) profilePhoto.width, profilePhoto.height = common.fullw, 180 

throws an error: profilePhoto a nil value “profilePhoto.width, profilePhoto.height = common.fullw, 180”

Try inserting "print("profilePhoto = “,profilePhoto)” into your function, right below display.newImage, as in:

 

local profilePhoto local function showPhoto( event ) if ( event.isError ) then print( "Network error - download failed: ", event.response ) elseif ( event.phase == "ended" ) then profilePhoto = display.newImage( event.response.filename, event.response.baseDirectory) print("profilePhoto = ",profilePhoto) end end network.download( url, "GET", showPhoto, "profile.png", system.TemporaryDirectory) profilePhoto.width, profilePhoto.height = common.fullw, 180

If the output is “profilePhoto = nil” then you have an error already in creating the image.

19:41:21.802  profilePhoto = table: 0CF54808

19:42:47.921  Scenes.setting

19:42:48.508  ERROR: Runtime error

19:42:48.508  C:\Users\Scenes\setting.lua:86: attempt to index local ‘profilePhoto’ (a nil value)

19:42:48.508  stack traceback:

19:42:48.508  C:\Users\Scenes\setting.lua:86: in function ‘?’

19:42:48.508  ?: in function ‘dispatchEvent’

19:42:48.508  ?: in function ‘_nextTransition’

19:42:48.508  ?: in function <?:1494>

19:42:48.508  (tail call): ?

19:42:48.508  ?: in function ‘?’

19:42:48.508  ?: in function <?:190>

19:42:49.108  profilePhoto = table: 12851A00

full console

If you run print (“profilePhoto =”, profilePhoto) outside the showPhoto function, nil displays. That’s the whole question why the value is not passed outside the function, and the variable is empty, despite the fact that the function is assigned a value

The console output doesn’t really help all that much as I have no idea what is on any of those lines of code and if we keep this up, then we will be here until spring. :stuck_out_tongue:

The fact is that you can manage variables as already mentioned, i.e.

 

-- -- #method 1: local rect local function define() rect = display.newRect( display.contentCenterX, display.contentCenterY, 100, 100) end define() -- #method 2: local function define() local object = display.newRect( display.contentCenterX, display.contentCenterY, 100, 100) return object end local rect = define()

Either way you’d have a variable named “rect” that you could manipulate outside of the function(s) where it is created. You may have the “a nil value” error for several reasons, in this case if the image exists, then your issue may lie with “common.fullw” not being defined. You need to do the debugging yourself now.

Your example is clear to me, but whatever I do I can’t control the contents of the variable outside the function

 local profilePhoto local function showPhoto( event ) if ( event.isError ) then print( "Network error - download failed: ", event.response ) elseif ( event.phase == "ended" ) then profilePhoto = display.newImage( event.response.filename, event.response.baseDirectory) print("profilePhoto = ", profilePhoto) -- table: 06E6F458 end return profilePhoto end network.download( "http://34766.ru/image/" .. settingJson.image, "GET", showPhoto, "profile.png", system.TemporaryDirectory) print("profilePhoto = ", profilePhoto) -- nil

When printing in the first case shows the data in the second case outputs nil

network.request is an asynchronous function. What that means is that the function showPhoto is not executed immediately. It waits until the file has been successfully (or unsuccessfully) downloaded, and then runs. It might be very quick for a small image, but equally that request could have been for an mp4 video and taken 30 seconds.

Therefore if you try and access profilePhoto immediately after calling network.request, it will be nil. Therefore any code that needs to act on profilePhoto needs to also wait until the listener showPhoto has executed, and should check to make sure the image exists before doing anything.

Then, how can we implement the specified property?

Why don’t you just do it within showPhoto? Or call another function from showPhoto?

Why don’t you just do it within showPhoto? 

I can work with the image in function, it is not difficult. I was more interested to understand why it didn’t work in my example. Thank you for enlightening me! Can you give an example of what you’re talking about?

[lua]

local profilePhoto

local hideImage = function ()

  print("profilePhoto in function called from listener: ", profilePhoto)

  profilePhoto.alpha = 0

end

local function showPhoto( event )

  if ( event.isError ) then

    print( "Network error - download failed: ", event.response )

  elseif ( event.phase == “ended” ) then

    profilePhoto = display.newImageRect( event.response.filename, event.response.baseDirectory,common.fullw, 180)

    print("profilePhoto in listener: ", profilePhoto)

    timer.performWithDelay(2000, hideImage) – hide image after 2 seconds

  end

  return profilePhoto

end

network.download( “http://34766.ru/image/” … settingJson.image, “GET”, showPhoto, “profile.png”, system.TemporaryDirectory)

print("profilePhoto immediately after download request: ", profilePhoto)

[/lua]

@eto,

That last line is wrong.  You are assuming that network.download() is blocking. 

It is NOT.  It does not wait for the file to download.  It submits the request and moves on immediately. 

So, the function executes and then goes to that last line of code, but the ‘profilePhoto’ variable has nothing assigned to it yet. 

You need to manipulate the variable in your listener.

You would either have to declare the variable before the function or return the variable from the function.

Here’s the same in pseudo-code:

 

-- #1: declare first local profilePhoto local function showPhoto() profilePhoto = display.newImage( event.response.filename, event.response.baseDirectory) end showPhoto() -- #2: return the variable local function showPhoto() local profilePhoto = display.newImage( event.response.filename, event.response.baseDirectory) return profilePhoto end local profilePhoto = showPhoto()