B4J Question [Banano] Converting httpjob code from B4A

toby

Well-Known Member
Licensed User
Longtime User
I just started learning Banano and I'm wondering how to convert the following piece of B4A code to Banano PWA. It would be great if someone could kindly give me a hint or two.

TIA

b4a code:
Dim map1 As Map = CreateMap("orderid": "12345678", "customer_id": "1234")
    
    Dim JSON As JSONGenerator
    JSON.Initialize(map1)
    Dim data As String = JSON.ToPrettyString(1) 'indent by 1 space

    Dim J As HttpJob 'depends OKHttpUtils2
    J.Initialize("J",Me)
    J.PostString("https://mysite.com/getdetail.php" , data )
        
    Wait For (j) JobDone(j As HttpJob)
    If j.Success=False Then
        j.Release
        Log("unable to get data")
    End If
    
    Dim parser As JSONParser
    parser.Initialize($"${J.GetString}"$)
    j.Release 'asap
    Dim lstResult As List
    lstResult.Initialize
    Try
        lstResult=parser.NextArray
    Catch
        Log(LastException)
    End Try
    
    For Each m As Map In lstResult 'ignore
        'go throught each record
        '''''''
    Next
 
Solution
Solution:
B4X:
  dim key as string="Test"
  msg=$"Test=${m.Get(key)}"$
  SKTools.ShowToast(msg, "info", 3000, True) 'output: Test=1

toby

Well-Known Member
Licensed User
Longtime User
Look at BANanoFetch in the manual to get started
BANanoFetch is very interesting and is better than php as far as dealing with database is concerned. For new projects, I'll definitely choose BANanoFetch.

I have implemented PHP backend already for an existing B4A app. I don't have time to reinvent the wheel for a new backend; Right now all I want is to develop a completmentary webapp and I would like to reuse the same PHP backend to interact with mysql.

How do I, without using BANanoFetch, send a simple post request, similar to the following
B4X:
 J.PostString("https://mysite.com/getdetail.php" , dataMap)
which returns a json string as the result.
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
For this example, I'm going to mimic a part of the HttpJob so we can reuse as much code as possible from your code.

New class HttpJob:
B4X:
Sub Class_Globals
    Private BANano As BANano 'ignore
    Private mName As String
    Private mString As String
    Private mError As String
  
    Public Success As Boolean  
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(Name As String, TargetModule As Object)
    ' TargetModule is not used here
    mName = Name  
End Sub

Public Sub PostString(url As String, data As String)
    ' reset some variables
    Success = False
    mError = ""
    mString = ""

    Dim fetch As BANanoFetch
    Dim fetchOptions As BANanoFetchOptions
    Dim fetchResponse As BANanoFetchResponse
  
    Dim jsonMap As Map
    Dim Error As String
  
    fetchOptions.Initialize
    fetchOptions.Method = "POST"
    fetchOptions.Body = data
    fetchOptions.Headers = CreateMap("Content-type": "application/json; charset=UTF-8")
    ' might need other headers, depending on what your php expects
  
    fetch.Initialize(url, fetchOptions)
    Try
        ' wait for the response
        fetchResponse = BANano.Await(fetch)
        ' wait for the json part of the response
        jsonMap = BANano.Await(fetchResponse.Json)
        ' overkill as we already have the json parsed here, but for compatibily's sake we convert it back to a Json string so we can do a GetString later
        Dim json As JSONGenerator
        json.Initialize(jsonMap)
        mString = json.ToString      
        ' we got it!
        Success = True      
    Catch(Error)  
        mError = Error      
    End Try  
End Sub

public Sub Release()
    ' dummy method to make it standard B4J compatible
End Sub

public Sub GetString() As String
    Return mString
End Sub

public Sub JobName() As String
    Return mName
End Sub

public Sub ErrorMessage() As String
    Return mError
End Sub

Usage (apart from the Wait For being replaced by a BANano.Await, the code should be identical):
B4X:
    Dim map1 As Map = CreateMap("orderid": "12345678", "customer_id": "1234")
  
    Dim JSON As JSONGenerator
    JSON.Initialize(map1)
    Dim data As String = JSON.ToPrettyString(1) 'indent by 1 space
  
    Dim J As HttpJob
    J.Initialize("J",Me)
    BANano.Await(J.PostString("https://mysite.com/getdetail.php" , data )) '<--- instead of the Wait For on the next line
              
    'Wait For (j) JobDone(j As HttpJob) '<--- we do not need this, the BANano.Await does this for us on the previous line
    If j.Success=False Then
        j.Release
        Log("unable to get data")
        Return '<--- this should've been in your original code too
    End If
  
    Dim parser As JSONParser
    parser.Initialize($"${J.GetString}"$)
    j.Release 'asap
    Dim lstResult As List
    lstResult.Initialize
    Try
        lstResult=parser.NextArray
    Catch
        Log(LastException)
    End Try
  
    For Each m As Map In lstResult 'ignore
        'go throught each record
        '''''''
    Next

Alwaysbusy
 
Last edited:
Upvote 0

toby

Well-Known Member
Licensed User
Longtime User
For this example, I'm going to mimic a part of the HttpJob so we can reuse as much code as possible from your code.


For Each m As Map In lstResult 'ignore
'go throught each record
'''''''
Next
[/code]

Alwaysbusy
It works almost perfectly. Thanks.

The only problem I have is that table column names have to be in lowercase. For example, "orderItem_Id" fails while "orderitem_id" works. Of course for select queries I could do something like "SELECT orderItem_Id as orderitem_id FROM orderItems ". Is there any easier way?
 
Upvote 0

toby

Well-Known Member
Licensed User
Longtime User
My php code just returns all columns as they're (SELECT * FROM orderitems).

You were right. Your code returns data correctly. Take note of the column name "Test".
Capitalize key "Test":
■[HttpJob: 49] [{"orderitem_id":"1","order_id":"1","qty":"1","amt":"15","Test":"1"},{"orderitem_id":"2","order_id":"1","qty":"2","amt":"20","Test":"1"}]


How I loop through each record:
    For Each m As Map In lstResult 'ignore
        'go throught each record
        '''''''
        Log(m)
        Dim msg As String=$"orderItem_id=${m.Get("orderitem_id")}"$
        SKTools.ShowToast(msg, "info", 3000, True)
        msg=$"qty=${m.Get("qty")}"$
        SKTools.ShowToast(msg, "info", 3000, True)
        msg=$"amt=${m.Get("amt")}"$
        SKTools.ShowToast(msg, "info", 3000, True)
        
        msg=$"Test=${m.Get("Test")}"$ '<<-this line causes the problem
        SKTools.ShowToast(msg, "info", 3000, True) 'Test="Undefined"
        
    Next
If I rename the table column name from "Test" to "test" and change above m.get("Test") to m.get("test"), it would return correct value. The problem might not be BANano related.
 
Upvote 0

toby

Well-Known Member
Licensed User
Longtime User
Solution:
B4X:
  dim key as string="Test"
  msg=$"Test=${m.Get(key)}"$
  SKTools.ShowToast(msg, "info", 3000, True) 'output: Test=1
 
Upvote 0
Solution
Top