Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

How can I manage variable outside of a function?
Started by eto_ru Jan 13 2019 02:54 AM

18 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

eto_ru

[GLOBAL: userInfoPane.html]
eto_ru
  • Enthusiast

  • 35 posts
  • Corona SDK

	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?



[TOPIC: post.html]
#2

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 582 posts
  • Corona SDK

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()


[TOPIC: post.html]
#3

eto_ru

[GLOBAL: userInfoPane.html]
eto_ru
  • Enthusiast

  • 35 posts
  • Corona SDK

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



[TOPIC: post.html]
#4

eto_ru

[GLOBAL: userInfoPane.html]
eto_ru
  • Enthusiast

  • 35 posts
  • Corona SDK

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



[TOPIC: post.html]
#5

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 582 posts
  • Corona SDK

Well, that's because you don't do what I suggested. :)

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.



[TOPIC: post.html]
#6

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 582 posts
  • Corona SDK

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.



[TOPIC: post.html]
#7

eto_ru

[GLOBAL: userInfoPane.html]
eto_ru
  • Enthusiast

  • 35 posts
  • Corona SDK

	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"



[TOPIC: post.html]
#8

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 582 posts
  • Corona SDK

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.



[TOPIC: post.html]
#9

eto_ru

[GLOBAL: userInfoPane.html]
eto_ru
  • Enthusiast

  • 35 posts
  • Corona SDK

19:41:21.802  profilePhoto = table: 0CF54808



[TOPIC: post.html]
#10

eto_ru

[GLOBAL: userInfoPane.html]
eto_ru
  • Enthusiast

  • 35 posts
  • Corona SDK

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


[TOPIC: post.html]
#11

eto_ru

[GLOBAL: userInfoPane.html]
eto_ru
  • Enthusiast

  • 35 posts
  • Corona SDK

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



[TOPIC: post.html]
#12

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 582 posts
  • Corona SDK

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. :P

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.

 

 



[TOPIC: post.html]
#13

eto_ru

[GLOBAL: userInfoPane.html]
eto_ru
  • Enthusiast

  • 35 posts
  • Corona SDK

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



[TOPIC: post.html]
#14

nick_sherman

[GLOBAL: userInfoPane.html]
nick_sherman
  • Corona Geek

  • 1,711 posts
  • Corona SDK

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.



[TOPIC: post.html]
#15

eto_ru

[GLOBAL: userInfoPane.html]
eto_ru
  • Enthusiast

  • 35 posts
  • Corona SDK

Then, how can we implement the specified property?



[TOPIC: post.html]
#16

nick_sherman

[GLOBAL: userInfoPane.html]
nick_sherman
  • Corona Geek

  • 1,711 posts
  • Corona SDK

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



[TOPIC: post.html]
#17

eto_ru

[GLOBAL: userInfoPane.html]
eto_ru
  • Enthusiast

  • 35 posts
  • Corona SDK

 

 

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?



[TOPIC: post.html]
#18

nick_sherman

[GLOBAL: userInfoPane.html]
nick_sherman
  • Corona Geek

  • 1,711 posts
  • Corona SDK

 
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)
 


[TOPIC: post.html]
#19

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,492 posts
  • Corona SDK

	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"

 

 

 

 

@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.


Edited by roaminggamer, 13 January 2019 - 11:30 AM.



[topic_controls]
[/topic_controls]