Waiting for coroutine to finish before main function continues

Hi All,

I am currently in a bit of a pickle. I have implemented an SSL network request as per the page: https://docs.coronalabs.com/api/library/network/request.html

I want to populate the variable response with json.decode(event.response), which I can do perfectly fine after calling network.request( URL , “GET”, networkListener ) [url hidden for obvious reasons]

Updating for clarification:

I have a single scene that is used for altering a data entry, it has three functions: new record, edit the current record before committing, and edit a record that has already been committed to the database.

if type(composer.getVariable("entry\_edit")) == "nil" or composer.getVariable("entry\_edit") == "0" then description\_box = "" -- brand new, so is set to blank string elseif composer.getVariable("entry\_edit") == "1" then description\_box = composer.getVariable("desc") -- this is from the previous scene elseif composer.getVariable("entry\_edit") == "2" then local URL = "https://blah.blah" -- the url goes here network.request( URL , "GET", networkListener ) -- ideally this should wait here until networkListener is FINISHED description\_box = response[i]['description'] -- this is retrieved from the pairs response from a database end -- the further in the scene, this runs desctextbox= native.newTextField( device.centerX+device.centerX\*0.5, display.actualContentHeight\*0.25, display.actualContentWidth\*0.4, font.contentFontSize\*1.4 ) desctextbox.inputType="no-emoji" desctextbox.text = description\_box -- put in here what ever is relevant, according to the script above

The problem is that lua/corona is getting to the desctextbox creation earlier prior to the networkListener completing, because locally creating the scene is taking less than 2-4ms, while the response from the webserver is taking up to 200ms. So when the scene is trying to create the textbox, if I am in the [lua]composer.getVariable(“entry_edit”) == “2”[/lua] mode, then I am trying to set an undeclared value (at that point in time, description_box is a nil value, because it has not been declared yet.

So yeah. The previous developer was using http socket connections, which can wait for a response, but this was sending usernames and passwords over clear text, which is not acceptable to the client, thus I am migrating to https, but that operates differently to the http socket connection. So now I have to wait for a response before the rest of the lua script/main routine continues.

Hope that someone might be able to point me in the right direction.

Cheers

Ryan Abrahams

Hi Ryan,

Not sure I understand the question correctly, but can’t you put all the code that populates the page into a function and call that function after the response has been recieved?

Hi Ammar,

I have updated the description of the problem that might hopefully clarify what the problem is, and what I need to do.

Regards

Ryan Abrahams

This is a common mistake with asynchronous functions.

What you should do is exactly what ammar71 already suggested.

Here’s some sample code with explanations, copied almost directly from the docs.

local function updateValues( args ) -- Optional function for updating values based on a successful network request. end local function networkListener( e ) if ( e.isError ) then print( "Network error: ", e.response ) -- The network request failed, so you can let the user know to try again later. else print ( "RESPONSE: " .. e.response ) -- The network request has finished successfully, so do whatever you want in here. -- Or, call another function from here to do what you need, e.g. updateValues( e.response ) end end -- Once this network request finishes, it will automatically call the listener. No need for coroutines. network.request( "https://encrypted.google.com", "GET", networkListener )

In addition to that, you can either:

  1. Draw your text fields, image rects but display placeholder info/images until the response is received.

  2. Don’t draw these and display some kind of loading message/busy indicator to show the app is working, only draw them when the data is available

  3. Draw them but hide them until the response is received, showing a message/busy indicator in the meantime.

Hi Ryan,

Not sure I understand the question correctly, but can’t you put all the code that populates the page into a function and call that function after the response has been recieved?

Hi Ammar,

I have updated the description of the problem that might hopefully clarify what the problem is, and what I need to do.

Regards

Ryan Abrahams

This is a common mistake with asynchronous functions.

What you should do is exactly what ammar71 already suggested.

Here’s some sample code with explanations, copied almost directly from the docs.

local function updateValues( args ) -- Optional function for updating values based on a successful network request. end local function networkListener( e ) if ( e.isError ) then print( "Network error: ", e.response ) -- The network request failed, so you can let the user know to try again later. else print ( "RESPONSE: " .. e.response ) -- The network request has finished successfully, so do whatever you want in here. -- Or, call another function from here to do what you need, e.g. updateValues( e.response ) end end -- Once this network request finishes, it will automatically call the listener. No need for coroutines. network.request( "https://encrypted.google.com", "GET", networkListener )

In addition to that, you can either:

  1. Draw your text fields, image rects but display placeholder info/images until the response is received.

  2. Don’t draw these and display some kind of loading message/busy indicator to show the app is working, only draw them when the data is available

  3. Draw them but hide them until the response is received, showing a message/busy indicator in the meantime.