2
votes

In one Lua file, I would like to call two APIs and obtain data from both at the same time. So far, I managed to call one API and print a data, but am not sure how to invoke the second call, using the string obtained from the first API call.

local json = require( "json" )
local function networkListener( event )
    local res = json.prettify( event.response )
    local decoded = json.decode( res )  
    if ( event.isError ) then
        print( "--Network error-- ", ( res ) )
    else
        print( "Data: " .. ( res ) )
        print(decoded.results.bindings[1].person.value)
        print(decoded.results.bindings[1].type.value)
        local dbpuri = decoded.results.bindings[1].person.value
        local wikititle = string.gsub(dbpuri, "http://dbpedia.org/resource/", "")
        print (wikititle)
    end
end

local headers = {}
headers["Content-Type"] = "application/json"
local body = ""
local params = {}
params.headers = headers

params.body = body
network.request("https://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=select+*%0D%0Awhere+{%3Fperson+rdfs%3Alabel+%3Fperson_name+%3B+rdf%3Atype+%3Ftype+%3B+dbo%3AbirthDate+%3Fbirthdate+.%0D%0A++++bind(rand(1+%2B+strlen(str(%3Fperson))*0)+as+%3Frid)%0D%0AFILTER+regex(%3Ftype%2C+%22Person%22)%0D%0A}+order+by+%3Frid%0D%0ALIMIT+10&format=text%2Fhtml&CXML_redir_for_subjs=121&CXML_redir_for_hrefs=&timeout=30000&debug=on&format=json", "GET", networkListener, params)

This is the 1st API call (success), but I would like to pass the local variable "wikititle" to invoke the 2nd API call. I added an almost identical code just below the previous code (See below), but it gets an error: "attempt to concatenate local 'wikititle' (a nil value)..."

local json = require( "json" )
local function networkListener( event )
    local res = json.prettify( event.response )
    local decoded = json.decode( res )  
    if ( event.isError ) then
        print( "--Network error-- ", ( res ) )
    else
        print( "Data: " .. ( res ) )
        print(decoded.query.pages.original.source)
        print(decoded.warnings.pageimages)
    end
end

local headers = {}
headers["Content-Type"] = "application/json"
local body = ""
local params = {}
params.headers = headers

params.body = body
network.request("https://en.wikipedia.org/w/api.php?action=query&prop=pageimages&format=json&piprop=original&titles="..wikititle.."", params)

I am a beginner in Lua, but can anybody help me to find a good solution? (I guess I should do with forward declaration, and it is best if I can avoid repeating the code for the two API calls in the code). Many thanks!

2

2 Answers

2
votes

you will need to use nested callbacks in this case. i would also split this special case into its own function instead of trying to use one monolithic function for everything. passing around unnamed functions to do work is fairly standard in the event based world where you don't have full control over the 'when' of things happen

local function getWikipediaData(event)
    local res = json.prettify( event.response )
    local decoded = json.decode( res )  

    if ( event.isError ) then
        print( "--Network error-- ", ( res ) )
        return
    end

    local dbpuri = decoded.results.bindings[1].person.value
    local wikititle = string.gsub(dbpuri, "http://dbpedia.org/resource/", "")
    network.request(
        "https://en.wikipedia.org/.../&titles=".. wikititle,
        "GET",
        function(event) 
            -- handle the wikipedia response here
        end,
        params)
end

network.request(
    "https://dbpedia.org/sparql?...", 
    "GET", 
    getWikipediaData,
    params);
0
votes

This is the answer I ended up with:

local json = require( "json" )
local function getWikipediaData( event )
    local res = json.prettify( event.response )
    local decoded = json.decode( res )  
    if ( event.isError ) then
        print( "--Network error-- ", ( res ) )
        return
    else
        print( "Data: " .. ( res ) )
        print(decoded.results.bindings[1].person.value)
        print(decoded.results.bindings[1].type.value)
        local dbpuri = decoded.results.bindings[1].person.value
        local wikititle = string.gsub(dbpuri, "http://dbpedia.org/resource/", "")
        print (wikititle)

        network.request(
                "https://en.wikipedia.org/w/api.php?action=query&prop=pageimages&format=json&piprop=original&titles="..wikititle,
                "GET",
                function(event) 
                    local res2 = json.prettify( event.response )
                    local decoded2 = json.decode( res2 )
                    print( "Data2: " .. ( res2 ) )
                    print(decoded2.query.normalized[1].to)
                end,
                params)
    end
end

local headers = {}
headers["Content-Type"] = "application/json"
local body = ""
local params = {}
params.headers = headers

params.body = body
network.request("https://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=select+*%0D%0Awhere+{%3Fperson+rdfs%3Alabel+%3Fperson_name+%3B+rdf%3Atype+%3Ftype+%3B+dbo%3AbirthDate+%3Fbirthdate+.%0D%0A++++bind(rand(1+%2B+strlen(str(%3Fperson))*0)+as+%3Frid)%0D%0AFILTER+regex(%3Ftype%2C+%22Person%22)%0D%0A}+order+by+%3Frid%0D%0ALIMIT+10&format=text%2Fhtml&CXML_redir_for_subjs=121&CXML_redir_for_hrefs=&timeout=30000&debug=on&format=json", "GET", networkListener, params)