Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Using loop and cascade network.request
Started by solca Mar 12 2018 05:40 AM

- - - - -
18 replies to this topic
network.request api rest loop cascade

Best Answer solca , 15 March 2018 - 06:40 AM

Thanks to Anaqim and Develephant for your answers.
 
Finally I solved the problem, passing the data from the sqlite table to a lua table, and from there I launch the process with a button (widget) for each record (row of the lua table).
 
Regards,
 
Solca

[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

solca

[GLOBAL: userInfoPane.html]
solca
  • Enthusiast

  • 64 posts
  • Corona SDK

Thanks in advance for your answers. The situation is the following:

 

1. I must process N times some records stored locally in sqlite

2. To process each record I must make a first network.request to a web service 01 and once this first request is finished, I must make a second network.request to a web service 02

3. I have tried to condense the code in this (N=3):

-- TEST WS
local json = require ("json")
print (os.date().." -------------- TEST WS START --------------------")

local function wsTest02Call( event )
	if ( event.isError ) then
        print( "Network error: ", event.response )
    else
        print ( os.date().." RESPONSE: " .. event.response )
    end
end

local function wsTest01Call( event )
	if ( event.isError ) then
        print( "Network error: ", event.response )
    else
        print ( os.date().." RESPONSE: " .. event.response )
        local response = json.decode( event.response )
            if (response.Status =="ok") then
            	local headers = {}
				headers["Content-Type"] = "application/x-www-form-urlencoded"
				headers["Accept-Language"] = "en-US" 
				headers["User-Agent"] = "My Corona APP"
				local body = "qty=50&priceunit=100"
				local params = {}
				params.headers = headers
				params.body = body
				params.timeout = 15 
				-- Call WS02
				network.request( "https://aws05.phonemas.com/ws/wstest02.php", "POST", wsTest02Call, params )  
            end
    end
end

local function callWS( )
	local headers = {}
	headers["Content-Type"] = "application/x-www-form-urlencoded"
	headers["Accept-Language"] = "en-US" 
	headers["User-Agent"] = "My Corona APP"
	local body = "color=red&size=small"
	local params = {}
	params.headers = headers
	params.body = body
	params.timeout = 15 
	-- CAL WS01
	network.request( "https://aws05.phonemas.com/ws/wstest01.php", "POST", wsTest01Call, params )  
end
-- LOOP 3 TIMES
for i=1,3 do
	callWS()
end
print (os.date().." -------------- TEST WS END --------------------")

The result is as follows:

Copyright © 2009-2018  C o r o n a   L a b s   I n c .

Version: 3.0.0

Build: 2018.3228

Loading project from:   ~/Documents/Corona Projects/Samples/Test WS

Project sandbox folder: ~/Library/Application Support/Corona Simulator/Test WS-81A8676CBB0C22A036E551B82F6EBB38

Platform: GT-I9300 / x86_64 / 10.12.6 / Intel HD Graphics 4000 OpenGL Engine / 2.1 INTEL-10.25.19 / 2018.3228 / en-CO | CO | en_CO | en

Mon Mar 12 08:16:08 2018 -------------- TEST WS START --------------------

Mon Mar 12 08:16:08 2018 -------------- TEST WS END --------------------

Mon Mar 12 08:16:11 2018 RESPONSE: {"Status":"ok","info":"MSG: Thank you. Processed requirement 01)"}

Mon Mar 12 08:16:11 2018 RESPONSE: {"Status":"ok","info":"MSG: Thank you. Processed requirement 01)"}

Mon Mar 12 08:16:11 2018 RESPONSE: {"Status":"ok","info":"MSG: Thank you. Processed requirement 01)"}

Mon Mar 12 08:16:15 2018 RESPONSE: {"Status":"ok","info":"MSG: Thank you. Processed requirement 02)"}

Mon Mar 12 08:16:15 2018 RESPONSE: {"Status":"ok","info":"MSG: Thank you. Processed requirement 02)"}

Mon Mar 12 08:16:15 2018 RESPONSE: {"Status":"ok","info":"MSG: Thank you. Processed requirement 02)"}

 

It is observed that they are not being executed as I need it (point 2).

 

The question is: How should I adjust my code to run in cascade (one behind the other)?

 

The URLs in the code are real and public, for those who wish to review.

 

Regards,

 

Solón



[TOPIC: post.html]
#2

anaqim

[GLOBAL: userInfoPane.html]
anaqim
  • Contributor

  • 770 posts
  • Corona SDK

a straight sequencial network calls function the way i do it (conceptual logic, not actual code)

local url="your_url"

local function callback(event)
   if event.reply then
      your code (perhaps storing result in a table)
      if there is a second call to be made
         url="your_new_url OR your_modified_url" 
         network.request(url,callback)
      else
         no more call desired so can exit function
      end
   else
      handle no reply, if reply was expected
      if if no more results is a desired end of function, exit function
   end
end

network.request(url,callback)


[TOPIC: post.html]
#3

solca

[GLOBAL: userInfoPane.html]
solca
  • Enthusiast

  • 64 posts
  • Corona SDK

Thanks Anaqim for your quick response.
 
According to your code, I should not have 2 listener functions separately, if not build a single listener. Is that correct?
 
Regards,
 
Solon


[TOPIC: post.html]
#4

anaqim

[GLOBAL: userInfoPane.html]
anaqim
  • Contributor

  • 770 posts
  • Corona SDK

That is all you need whether you do a single call or several sequencial calls.

 

The second and subsequent network calls are made from within the listener function.

Thats what makes this call loop sequencial.

 

Headers will usually be the same, so declare them at the top with the url, although you can easily set all new parameters in the reply just before making the next call.

 

Hope that makes sense.



[TOPIC: post.html]
#5

solca

[GLOBAL: userInfoPane.html]
solca
  • Enthusiast

  • 64 posts
  • Corona SDK

Thanks again Anaqim. Your help has been very important.
 
I have to adjust the scripts of the webservices (PHP) for it.
 
Regards,
 
Solon


[TOPIC: post.html]
#6

anaqim

[GLOBAL: userInfoPane.html]
anaqim
  • Contributor

  • 770 posts
  • Corona SDK

Happy to help mate

Hope it works out for you  :)



[TOPIC: post.html]
#7

solca

[GLOBAL: userInfoPane.html]
solca
  • Enthusiast

  • 64 posts
  • Corona SDK

Greetings Anaqim.
 
I have already configured the process of running the ws in cascade, according to your suggestion.
 
I have not yet been able to get that process to run in a loop (The real case is that I'm going through a sqlite database and I have to process each record)
 
Can you suggest something to run in a loop?
 
Thank you,
 
Solon
 
PS: I did not have to modify the PHP scripts, only Corona sdk.
 


[TOPIC: post.html]
#8

anaqim

[GLOBAL: userInfoPane.html]
anaqim
  • Contributor

  • 770 posts
  • Corona SDK

Hi there,

 

If you are talking about processing each record received from the network call agains a local sqllite base, that is easy.

Show me the relevant code bit with you network call and I'll see if I notice anything



[TOPIC: post.html]
#9

solca

[GLOBAL: userInfoPane.html]
solca
  • Enthusiast

  • 64 posts
  • Corona SDK

Thanks again,

 

Without the FOR-LOOP, it can be seen that the cascade process works for a call. This is the code for test:

-- TEST WS
local json = require ("json")

print (os.date().." -------------- WS 01 START --------------------")
-- WS Headers
local headers = {}
headers["Content-Type"] = "application/x-www-form-urlencoded"
headers["Accept-Language"] = "en-US" 
headers["User-Agent"] = "My Corona APP"
-- Functions
local function wsTest02Call( event )
	if ( event.isError ) then
        print( "Network error: ", event.response )
    else
        print ( os.date().." RESPONSE: " .. event.response )
        print (os.date().." -------------- WS 02 END --------------------")
    end
end
 
local function wsTest01Call( event )
	if ( event.isError ) then
        print( "Network error: ", event.response )
    else
        print ( os.date().." RESPONSE: " .. event.response )
        local response = json.decode( event.response )
            if (response.Status =="ok") then
				local body = "qty=50&priceunit=100"
				local params = {}
				params.headers = headers
				params.body = body
				params.timeout = 15 
				print (os.date().." -------------- WS 01 END --------------------")
				print (os.date().." -------------- WS 02 START --------------------")
				network.request( "https://aws05.phonemas.com/ws/wstest02.php", "POST", wsTest02Call, params ) 
            end
    end
end
-- Variables
local N = 3 -- # records in local DB

--for i=1,N do
	print("Procesing Record #")
	local body = "color=red&size=small"
	local params = {}
	params.headers = headers
	params.body = body
	params.timeout = 15 
	-- CAL WS01
	network.request( "https://aws05.phonemas.com/ws/wstest01.php", "POST", wsTest01Call, params )  
--end



[TOPIC: post.html]
#10

Develephant

[GLOBAL: userInfoPane.html]
Develephant
  • Corona Geek

  • 1,473 posts
  • Corona SDK

Hi,

 

Being the fact that network calls are asynchronous, when you issue them in a loop like that is just going to call all of the requests in one go.

 

You would need to implement a queuing system of some type using another table and then process each call as the response is returned.

 

-dev



[TOPIC: post.html]
#11

anaqim

[GLOBAL: userInfoPane.html]
anaqim
  • Contributor

  • 770 posts
  • Corona SDK

which is what my code above does.

 

i call it making them sequencial, meaning call 2 doesnt trigger before call 1 has replied, call 3 doesnt trigger until call 2 has replied, and so on.



[TOPIC: post.html]
#12

Develephant

[GLOBAL: userInfoPane.html]
Develephant
  • Corona Geek

  • 1,473 posts
  • Corona SDK

Hi,

 

I could be totally wrong here, but from what I gather, there is a set of sqlite records, and each one needs to make basically 2 network calls per record, in sequence, which the code @anaqim posted does indeed handle.

 

The issue is that you can't just run a for loop over the database records and and call the network requests.

--for i=1,N do
	print("Procesing Record #")
	local body = "color=red&size=small"
	local params = {}
	params.headers = headers
	params.body = body
	params.timeout = 15 
	-- CAL WS01
	network.request( "https://aws05.phonemas.com/ws/wstest01.php", "POST", wsTest01Call, params )  
--end

The requests will be coming back at different times, and most likely will overlap in places.

 

You would need to gather all the database record data into a table array and then call the request per each entry and wait for the response before issuing the next request set. You could do this using the requestId returned from the network call for example.

 

Again, I could be totally misunderstanding the use case.

 

-dev



[TOPIC: post.html]
#13

solca

[GLOBAL: userInfoPane.html]
solca
  • Enthusiast

  • 64 posts
  • Corona SDK

  Best Answer

Thanks to Anaqim and Develephant for your answers.
 
Finally I solved the problem, passing the data from the sqlite table to a lua table, and from there I launch the process with a button (widget) for each record (row of the lua table).
 
Regards,
 
Solca


[TOPIC: post.html]
#14

anaqim

[GLOBAL: userInfoPane.html]
anaqim
  • Contributor

  • 770 posts
  • Corona SDK

Pressing a button for each record isnt optimal is it? Unless you have only a few records.

Why not put the button event code on a timer instead? :)

[TOPIC: post.html]
#15

Develephant

[GLOBAL: userInfoPane.html]
Develephant
  • Corona Geek

  • 1,473 posts
  • Corona SDK

Or add a score field, and then it's a game.  :D

 

-dev



[TOPIC: post.html]
#16

solca

[GLOBAL: userInfoPane.html]
solca
  • Enthusiast

  • 64 posts
  • Corona SDK

Your comment is correct.
 
For practical purposes of the use case that I am solving, it is fine.
 
In another scenario (like batch) maybe not.
 
Thanks again.


[TOPIC: post.html]
#17

solca

[GLOBAL: userInfoPane.html]
solca
  • Enthusiast

  • 64 posts
  • Corona SDK

Pressing a button for each record isnt optimal is it? Unless you have only a few records.

Why not put the button event code on a timer instead? :)

 

How could this be?



[TOPIC: post.html]
#18

anaqim

[GLOBAL: userInfoPane.html]
anaqim
  • Contributor

  • 770 posts
  • Corona SDK

Got me a good laugh today, thx dev 😀
Solca, glad if it helps. Have a great one!

[TOPIC: post.html]
#19

anaqim

[GLOBAL: userInfoPane.html]
anaqim
  • Contributor

  • 770 posts
  • Corona SDK

Im sorry i dont get the question


[topic_controls]
[/topic_controls]