For-Loop Continues Background Execution During native.showalert

I am reading data from a table and need for the player to answer a few questions via a native.showalert if a certain condition is true (id = true). See example below. My problem is that the code will loop through all 5 records and only show the alert on the last record that meets the condition (Sally Anne). I need for it to finish up the inner code before going on to the next record in the for-loop.

According to the documentation the code will continue in the background on a native.showalert so I understand why and what the code is doing so what I am really asking for are ideas on other ways around this without having to write my own version of native.showalert.

Thanks ahead of time!

Scott

 local data = {     {name = "Jim Smith", id = false},     {name = "Jane Doe", id = true},     {name = "John Gee", id = false},     {name = "Sally Anne", id = true},     {name = "Freddie Mac", id = false} }     for j = 1, #data do     print("j", j, "id", data[j].id)     if data[j].id == true then         local function onLevel( event )                if event.action == "clicked" then                 local action = event.index                 if action == 3 then                     local levelText = "Rookie"                 elseif action == 2 then                     levelText = "All-Star"                 end                 local function onComplete( event )                        if event.action == "clicked" then                         local action2 = event.index                         if action2 == 1 then                             print("made it to inner alert")                         end                     end                 end                 native.showAlert( "Notification", "Are you sure you want to send this game request?", { "OK", "Cancel" }, onComplete )             end         end         native.showAlert( "Notification", "What level do you wish to play "..data[j].name.."?", { "Cancel", "All-Star", "Rookie" }, onLevel )     end end

Here is the output from the code. The “made it to inner showalert” only prints after user interacts with the last alert.

20:34:29.555  j    1    id    false
20:34:29.555  j    2    id    true
20:34:29.555  j    3    id    false
20:34:29.555  j    4    id    true
20:34:29.555  j    5    id    false
20:34:40.542  made it to inner alert
 

Hey gsglawson,

the solution to this is to not use a for loop.

The steps would be the following:

  1. Set up a local variable “questionCount” that counts at which question you are, starting with 1.

  2. Load the first question and open the alert.

  3. After the player answered increment “questionCount” by 1 one.

  4. Load the next question based of the value of “questionCount”.

  5. Repeat till you are done with questions.

Hope that helps to get you on the right track :slight_smile:

Greetings

Torben

Something like this should do the trick. Not tested as don’t have Corona on this machine. When you need the routine to run, set alertLoop to true.

[lua]

local alertLoop = false       – are we currently looping through players and asking for level?

local playerWaiting = false         – are we waiting for a response from a player

local player = 0                     – the current player we are processing

local data = {

    {name = “Jim Smith”, id = false},

    {name = “Jane Doe”, id = true},

    {name = “John Gee”, id = false},

    {name = “Sally Anne”, id = true},

    {name = “Freddie Mac”, id = false}

}   

 local function onLevel( event )  

            if event.action == “clicked” then

                local action = event.index

                        local levelText = “All-Star”

                if action == 2 then

                    levelText = “Rookie”

                end

                

                local function onComplete( event )   

                    if event.action == “clicked” then

                        local action2 = event.index

                        if action2 == 1 then

                            print(“made it to inner alert”)

                        end

                    end

                              playerWaiting = false

                end

                native.showAlert( “Notification”, “Are you sure you want to send this game request?”, { “OK”, “Cancel” }, onComplete )

            end

 end

local gameLoop = function ()

      if alertLoop then       – if we are currently looping through the players

     

            if playerWaiting == false then      – and not waiting for a response from a player

     

                  player = player + 1            – move on to the next player

                  if player > #data then        – if ran out of players

                        alertLoop = false       – stop looping. Call next section of code here.

                  else

                        local d = data[player]  – link to the current player in the data table

                        if d.id == true then          – if response required from player

                              playerWaiting = true  – need to wait for response from this player

                              native.showAlert( “Notification”, “What level do you wish to play " …d.n ame. .”?", { “Cancel”, “All-Star”, “Rookie” }, onLevel )

                        else

                              – no response required. On next frame the next player will be processed

                        end

                  end

            end

      end

end

Runtime:addEventListener(“enterFrame”, gameLoop)

[/lua]

Torben, thanks for the reply. I think you and Nick are basically saying the same thing.

Nick this worked perfectly and is exactly what I needed. Thanks again! This is a very supportive community!

Hey gsglawson,

the solution to this is to not use a for loop.

The steps would be the following:

  1. Set up a local variable “questionCount” that counts at which question you are, starting with 1.

  2. Load the first question and open the alert.

  3. After the player answered increment “questionCount” by 1 one.

  4. Load the next question based of the value of “questionCount”.

  5. Repeat till you are done with questions.

Hope that helps to get you on the right track :slight_smile:

Greetings

Torben

Something like this should do the trick. Not tested as don’t have Corona on this machine. When you need the routine to run, set alertLoop to true.

[lua]

local alertLoop = false       – are we currently looping through players and asking for level?

local playerWaiting = false         – are we waiting for a response from a player

local player = 0                     – the current player we are processing

local data = {

    {name = “Jim Smith”, id = false},

    {name = “Jane Doe”, id = true},

    {name = “John Gee”, id = false},

    {name = “Sally Anne”, id = true},

    {name = “Freddie Mac”, id = false}

}   

 local function onLevel( event )  

            if event.action == “clicked” then

                local action = event.index

                        local levelText = “All-Star”

                if action == 2 then

                    levelText = “Rookie”

                end

                

                local function onComplete( event )   

                    if event.action == “clicked” then

                        local action2 = event.index

                        if action2 == 1 then

                            print(“made it to inner alert”)

                        end

                    end

                              playerWaiting = false

                end

                native.showAlert( “Notification”, “Are you sure you want to send this game request?”, { “OK”, “Cancel” }, onComplete )

            end

 end

local gameLoop = function ()

      if alertLoop then       – if we are currently looping through the players

     

            if playerWaiting == false then      – and not waiting for a response from a player

     

                  player = player + 1            – move on to the next player

                  if player > #data then        – if ran out of players

                        alertLoop = false       – stop looping. Call next section of code here.

                  else

                        local d = data[player]  – link to the current player in the data table

                        if d.id == true then          – if response required from player

                              playerWaiting = true  – need to wait for response from this player

                              native.showAlert( “Notification”, “What level do you wish to play " …d.n ame. .”?", { “Cancel”, “All-Star”, “Rookie” }, onLevel )

                        else

                              – no response required. On next frame the next player will be processed

                        end

                  end

            end

      end

end

Runtime:addEventListener(“enterFrame”, gameLoop)

[/lua]

Torben, thanks for the reply. I think you and Nick are basically saying the same thing.

Nick this worked perfectly and is exactly what I needed. Thanks again! This is a very supportive community!