How to make code wait when calling backend?

Hi,

I am using Corona with GameSparks and I am making a username registrationRequest following this guide on GameSparks.

I made a Module in Corona and created a function using

M.registerUser = function(userName) local result = { status = '', errorMsg = '' } -- Make backend call -- On backend response, set result values ('success' or 'failed') return result end

Then I have a login.lua file that makes a scene with the following function

local function createUserListener(event) if (event.phase == "submitted") then local username = event.target.text local register = authentication.registerUser(username) if (register.status == "success") then -- Great, call function to make new player elseif (register.status == "failed") then -- Failed to register username end end

So the backend is taking longer than the code takes to execute and I’m getting the expected error: register is nil

How do I make the function wait for register to have a value?

Can someone show code example of using callbacks or making an event listener?

I could put the registerUser function in the createUserListener function but I want to be able to use modules.

Thanks.

Hi.  You can’t handle it that way because the function you wrote isn’t going to wait for the response.  It will initiate the request and continue on.

All remote accesses to the service require a callback.

It seems you want to write the code so it is ‘gated’ by your function call.  That won’t work.  

You need to make the request(s), then when they complete and call the callback(s), call other functions in your code to execute the appropriate actions.

This is the pain that is asynchronous event handling and a fact of life with all game servers, ads, etc.

That’s what I thought but can I do that using modules in Corona? Or will I have to make the request in the login.lua scene?

Modules are simply a way to organize your code, so “Sure, you can put this code into a module.”

@roaminggamer But how do I call a function in login.lua from a module? Would I have to make a callback function in my login page? Sorry for the newbie questions.

To call a function from a module you create the function in a file like so:

local M = {} function M.print(string) print(string) end return M

Then in the file, you need the function:

local functions = require "functions" functions.print("Something was printed");

@sdktester15 Thanks for your input but that example is a bit confusing. I don’t think it does what I need to do.

First let’s rename the function because calling it print is confusing with the built-in print function. Second, I have 2 functions in my file where the second one needs to be called from the Module like so:

local M = {} function M.doSomething(string) print(string) -- Need to call secondFunction from here. end return M

Then in the file, I have:

local functions = require "functions" local function firstFunction(string) functions.doSomething(string) end local function secondFunction() -- This should be called from Module end

So my file has 2 functions where the second one needs to be called *after* the doSomething function has completed.

I think I may have to just bring the doSomething function into the file if there is no other way. Unless both functions require each other?

He is demoing the concept of a module.

You have to understand how modules work before bundling your code in one will make sense.

Note: I can’t really help with this as it would involve writing  a rather extensive bit of code.

Maybe something like the following would help …

local M = {} function M.doSomething(string, callback) print(string) callback() end return M

Then re-arrange slightly …

local functions = require "functions" local function secondFunction() -- This should be called from Module end local function firstFunction(string) functions.doSomething(string, secondFunction) end

Corona is an event driven system. The idea of knowing when something is complete via a return value isn’t very practical. Almost all things that take time, like your registration event involves using what’s called a “Call back listener”. It’s a function you write to react to the long lived action being complete.  Since it’s your function, you can then start up whatever action you need to as to get your app going on.

In this case perhaps you should so some activity indicator so that it shows busy. When your call back function triggers, you can turn off the activity indicator and then move your app to the screen you want to after a successful login.

Rob

Hi.  You can’t handle it that way because the function you wrote isn’t going to wait for the response.  It will initiate the request and continue on.

All remote accesses to the service require a callback.

It seems you want to write the code so it is ‘gated’ by your function call.  That won’t work.  

You need to make the request(s), then when they complete and call the callback(s), call other functions in your code to execute the appropriate actions.

This is the pain that is asynchronous event handling and a fact of life with all game servers, ads, etc.

That’s what I thought but can I do that using modules in Corona? Or will I have to make the request in the login.lua scene?

Modules are simply a way to organize your code, so “Sure, you can put this code into a module.”

@roaminggamer But how do I call a function in login.lua from a module? Would I have to make a callback function in my login page? Sorry for the newbie questions.

To call a function from a module you create the function in a file like so:

local M = {} function M.print(string) print(string) end return M

Then in the file, you need the function:

local functions = require "functions" functions.print("Something was printed");

@sdktester15 Thanks for your input but that example is a bit confusing. I don’t think it does what I need to do.

First let’s rename the function because calling it print is confusing with the built-in print function. Second, I have 2 functions in my file where the second one needs to be called from the Module like so:

local M = {} function M.doSomething(string) print(string) -- Need to call secondFunction from here. end return M

Then in the file, I have:

local functions = require "functions" local function firstFunction(string) functions.doSomething(string) end local function secondFunction() -- This should be called from Module end

So my file has 2 functions where the second one needs to be called *after* the doSomething function has completed.

I think I may have to just bring the doSomething function into the file if there is no other way. Unless both functions require each other?

He is demoing the concept of a module.

You have to understand how modules work before bundling your code in one will make sense.

Note: I can’t really help with this as it would involve writing  a rather extensive bit of code.

Maybe something like the following would help …

local M = {} function M.doSomething(string, callback) print(string) callback() end return M

Then re-arrange slightly …

local functions = require "functions" local function secondFunction() -- This should be called from Module end local function firstFunction(string) functions.doSomething(string, secondFunction) end

Corona is an event driven system. The idea of knowing when something is complete via a return value isn’t very practical. Almost all things that take time, like your registration event involves using what’s called a “Call back listener”. It’s a function you write to react to the long lived action being complete.  Since it’s your function, you can then start up whatever action you need to as to get your app going on.

In this case perhaps you should so some activity indicator so that it shows busy. When your call back function triggers, you can turn off the activity indicator and then move your app to the screen you want to after a successful login.

Rob