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:-
PHP Code to return JSON data from MYSQL:
  $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));

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.
Postman output:
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
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.

B4A code, errors at line 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
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
Use NextObject and Map:
If Job.Success Then
        Dim parser As JSONParser
        parser.Initialize(Job.GetString)
        callout = parser.NextObject
        Log("CalloutList: " & callout.Get("client_id"))
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.
 

MarcoRome

Expert
Licensed User
Longtime User
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

mcqueccu

Well-Known Member
Licensed User
Longtime User
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

RogerW

Member
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?
What is ,<text>:
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")

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

I also have to admit that previously I posted the wrong code for the url, it should have been
B4X:
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

RogerW

Member
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.
Working code:
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

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

KMatle

Expert
Licensed User
Longtime User
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
Top