Android Question PHP API to B4A App

RogerW

Member
I am trying to write a simple API to allow my B4A app to get data from a MySQL database.

The problem I keep coming up against is that I cannot get B4A to correctly read the data that is sent across, I think this is due to a fundamental misunderstanding of what I am trying to achieve. Anyway here is my PHP Code:-
[CODE lang="b4x" title="PHP Code to return JSON data from MYSQL" highlight="23"] $dblink = new mysqli($dbhost, $dbuser, $dbpass, $dbname);

//Check connection was successful
if ($dblink->connect_errno) {
printf("Failed to connect to database");
exit();
}

//Fetch rows from table
$result = $dblink->query("SELECT callout.id, callout.client_id, callout.time, callout.date, callout.description, callout.notes, callout.started, callout.completed, customer.first_name, customer.last_name, address.add_1, address.add_2, address.town, address.city, address.postcode FROM callout
LEFT JOIN customer on callout.client_id = customer.cust_id
LEFT JOIN address on customer.address_id = address.address_id");

//Initialize array variable
$dbdata = array();

//Fetch into associative array
while ( $row = $result->fetch_assoc()) {
$dbdata[]=$row;
}

//Print array in JSON format
echo json_encode(var_dump($dbdata));[/CODE]

This is returning the data that I wanted to read in the B4A app, am I returning an array? I think so!

I have used Postman check and this is what it receives.
[CODE lang="b4x" title="Postman output" highlight="1"]array(2) {
[0]=>
array(15) {
["id"]=>
string(1) "1"
["client_id"]=>
string(4) "5072"
["time"]=>
string(5) "10:00"
["date"]=>
string(10) "20/10/2020"
["description"]=>
string(52) "Problems receiving emails from Gmail and Outlook.com"
["notes"]=>
string(47) "Come round the back and knock on the shed door."
["started"]=>
string(0) ""
["completed"]=>
string(0) ""
["first_name"]=>
string(16) "Andrew "
["last_name"]=>
string(20) "Test "
["add_1"]=>
string(25) "1 Any Stret "
["add_2"]=>
string(35) " "
["town"]=>
string(8) "Any Town"
["city"]=>
string(9) "Any Where"
["postcode"]=>
string(7) "AW1 1AW"
}
[1]=>
array(15) {
["id"]=>
string(1) "2"
["client_id"]=>
string(4) "5072"
["time"]=>
string(5) "11:00"
["date"]=>
string(10) "20/10/2020"
["description"]=>
string(67) "Problems with computer shutting down when customer is away from it."
["notes"]=>
string(28) "Customer is going out at 2pm"
["started"]=>
string(0) ""
["completed"]=>
string(0) ""
["first_name"]=>
string(16) "Andrew "
["last_name"]=>
string(20) "Test "
["add_1"]=>
string(25) "1 Any Stret "
["add_2"]=>
string(35) " "
["town"]=>
string(8) "Any Town"
["city"]=>
string(9) "Any Where"
["postcode"]=>
string(7) "AW1 1AW"
}
}
null[/CODE]
So it looks like I have an array.

If I make an API call from B4A I get the same data returned, however I keep getting errors in B4A.

[CODE lang="b4x" title="B4A code, errors at line 12" highlight="12"]Private Sub getJsonFromServer()
Dim Job As HttpJob
Dim calloutList As List
Dim callout As Map

Job.Initialize("api", Me) ' Init HttpJob
Job.PostString("https://nortechcomputers.co.uk/nortech/v1.0/api/read.php","") ' POST to url
Wait For (Job) JobDone(Job As HttpJob)
If Job.Success Then
Dim parser As JSONParser
parser.Initialize(Job.GetString)
[CODE lang="b4x" title="Line 12" highlight="1"]calloutList = parser.NextObject[/CODE]
Log("CalloutList: " & callout.Get("client_id"))

End If
Job.Release
End Sub[/CODE]

java.lang.RuntimeException: JSON Array expected.

So it looks to me like B4A thinks this isn't an array, so instead I will try and treat it as an object
[CODE lang="b4x" title="Use NextObject and Map" highlight="4"]If Job.Success Then
Dim parser As JSONParser
parser.Initialize(Job.GetString)
callout = parser.NextObject
Log("CalloutList: " & callout.Get("client_id"))[/CODE]
Now this gets rid of the error message, but the Log always says
CalloutList: null

Clearly I have no idea what i am doing, but can someone please point me in the right direction, I have been going in circles for ages with this.
 
Is right if you call in POST without parameter

B4X:
 Job.PostString("https://nortechcomputers.co.uk/nortech/v1.0/api/read.php","") ' POST to url

, come back with all value = NULL.

1604559230855.png
 
Upvote 0
What @MarcoRome posted is what i also got.
You can ignore the var_dump if you dont need the extra information.

B4X:
//Print array in JSON format
echo json_encode($dbdata);

You can then copy the result into this online json parser http://basic4ppc.com:51042/json/index.html to get the code to use

B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim callout As List = root.Get("callout")
For Each colcallout As Map In callout
 Dim date As String = colcallout.Get("date")
 Dim notes As String = colcallout.Get("notes")
 Dim description As String = colcallout.Get("description")
 Dim started As String = colcallout.Get("started")
 Dim id As String = colcallout.Get("id")
 Dim time As String = colcallout.Get("time")
 Dim completed As String = colcallout.Get("completed")
 Dim client_id As String = colcallout.Get("client_id")
Next
Dim itemCount As Int = root.Get("itemCount")
 
Upvote 0
What @MarcoRome posted is what i also got.
You can ignore the var_dump if you dont need the extra information.

B4X:
//Print array in JSON format
echo json_encode($dbdata);

You can then copy the result into this online json parser http://basic4ppc.com:51042/json/index.html to get the code to use

B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim callout As List = root.Get("callout")
For Each colcallout As Map In callout
Dim date As String = colcallout.Get("date")
Dim notes As String = colcallout.Get("notes")
Dim description As String = colcallout.Get("description")
Dim started As String = colcallout.Get("started")
Dim id As String = colcallout.Get("id")
Dim time As String = colcallout.Get("time")
Dim completed As String = colcallout.Get("completed")
Dim client_id As String = colcallout.Get("client_id")
Next
Dim itemCount As Int = root.Get("itemCount")
Thanks for the reply, and the link to the online parser, it is now starting to make sense, however one line seems to be throwing an error?
[CODE lang="b4x" title="What is ,<text>" highlight="2"]Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim callout As List = root.Get("callout")
For Each colcallout As Map In callout
Dim date As String = colcallout.Get("date")
Dim notes As String = colcallout.Get("notes")
Dim description As String = colcallout.Get("description")
Dim started As String = colcallout.Get("started")
Dim id As String = colcallout.Get("id")
Dim time As String = colcallout.Get("time")
Dim completed As String = colcallout.Get("completed")
Dim client_id As String = colcallout.Get("client_id")
Next
Dim itemCount As Int = root.Get("itemCount")[/CODE]

It says
Undeclared variable <text> is used before it was assigned any value
Previously this said
Code:
 parser.initialize(Job.GetString)

I also have to admit that previously I posted the wrong code for the url, it should have been
Code:
Job.PostString("https://nortechcomputers.co.uk/nortech/v1.0/api/test1.php","") ' POST to url
as this url doesn't give a null result.
 
Upvote 0
OK, the penny has just dropped, thanks to mcqueccu and the online parser

I have modified my code as follows and I am pleased to say that it is working.
[CODE lang="b4x" title="Working code" highlight="5,9,10,11,27,28"]Private Sub getJsonFromServer()
Dim Job As HttpJob

Job.Initialize("api", Me) ' Init HttpJob
Job.PostString("https://nortechcomputers.co.uk/nortech/v1.0/api/test1.php","") ' POST to url
Wait For (Job) JobDone(Job As HttpJob)
If Job.Success Then
Dim parser As JSONParser
parser.Initialize(Job.GetString)
Dim root As List = parser.NextArray
For Each colroot As Map In root
Dim date As String = colroot.Get("date")
Dim notes As String = colroot.Get("notes")
Dim town As String = colroot.Get("town")
Dim city As String = colroot.Get("city")
Dim postcode As String = colroot.Get("postcode")
Dim description As String = colroot.Get("description")
Dim last_name As String = colroot.Get("last_name")
Dim started As String = colroot.Get("started")
Dim completed As String = colroot.Get("completed")
Dim client_id As String = colroot.Get("client_id")
Dim add_2 As String = colroot.Get("add_2")
Dim add_1 As String = colroot.Get("add_1")
Dim id As String = colroot.Get("id")
Dim time As String = colroot.Get("time")
Dim first_name As String = colroot.Get("first_name")
Log("client_id = " & client_id)
Log("description = " & description)
Next
End If
Job.Release
End Sub[/CODE]

Now I understand how this works I can sit down and concentrate on writing some real code to get my app developed.

Thanks again.
 
Upvote 0
Hint: [ starts a list, { a map.

The returned JSON will be clearer if you use

B4X:
echo json_encode($dbdata);

as var_dump formats the array additionally to display on the screen (f.e. for a quick test to see how the contents "look")
 
Upvote 0
Back
Top