B4J Question Parsing JSON

Declan

Well-Known Member
Licensed User
Longtime User
I have the following code that must parse a JSON string/file received from the Sigfox cloud.
B4X:
Sub AStream_NewData (Buffer() As Byte)
    Dim MyStr As String
    MyStr = BytesToString(Buffer,0,Buffer.Length,"UTF8")

    Log(MyStr)
    
    Dim JSON As JSONParser
    Dim Map1 As Map
    JSON.Initialize(MyStr)
    Map1 = JSON.NextObject
    Dim m As Map 'helper map for navigating
    Dim MenuItems As List
    m = Map1.Get("menu")
    m = m.Get("popup")
    MenuItems = m.Get("menuitem")
    For i = 0 To MenuItems.Size - 1
        m = MenuItems.Get(i)
        Log(m.Get("deviceID"))
        Log(m.Get("itime"))
        Log(m.Get("data"))
    Next
End Sub
The JSON file that is sent from the Sigfox cloud is:
B4X:
{"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"deviceID":"{device}",
        "itime":"{time}",
        "data":"{data}"}
    ]
  }
}}
This was assembled using the B4J Network example.
I receive the following error - and after pull hair for a few hours, I need assistance.
B4X:
main._astream_newdata (java line: 106)
java.lang.RuntimeException: JSON Object expected.
    at anywheresoftware.b4j.objects.collections.JSONParser.NextObject(JSONParser.java:50)
    at b4j.example.main._astream_newdata(main.java:106)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
    at anywheresoftware.b4a.BA$2.run(BA.java:230)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:834)
 

Pendrush

Well-Known Member
Licensed User
Longtime User
Get code from here:

B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim menu As Map = root.Get("menu")
Dim popup As Map = menu.Get("popup")
Dim menuitem As List = popup.Get("menuitem")
For Each colmenuitem As Map In menuitem
    Dim data As String = colmenuitem.Get("data")
    Dim itime As String = colmenuitem.Get("itime")
    Dim deviceID As String = colmenuitem.Get("deviceID")
Next
Dim id As String = menu.Get("id")
Dim value As String = menu.Get("value")
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
@Pendrush
Many Thanks.
I have a problem here:
B4X:
Sub AStream_NewData (Buffer() As Byte)
    Dim MyStr As String
    MyStr = BytesToString(Buffer,0,Buffer.Length,"UTF8")
I am not converting to the correct character set - or something else is dodgy.
The Buffer contains the JSON file
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
I have a problem here
the error above does not come from this lines.

What is the content of MyStr after the call to BytesToString?
Add a log statement to find out
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
@DonManfred
Thanks for your input
My problem is with the data I am getting in on the Port as in Post #5
If I load a JSON file from "File.DirAssets", I am able to parse the data no problem.
I cannot understand why I am unable to get the correct text.
 
Upvote 0

Declan

Well-Known Member
Licensed User
Longtime User
I have attached the project
If you click the "JSON Test" button, you can see the Log
 

Attachments

  • 1.zip
    5 KB · Views: 149
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
I think you will need to use byteconverter lib and post what you actually receive, not what you expect to receive
B4X:
Sub AStream_NewData (Buffer() As Byte)
dim bc as ByteConverter
log( bc.HexFromBytes(Buffer) ) ' <<< post what this produces
...
Then it will be possible to work out what character encoding is being used on the received data
 
Last edited:
Upvote 0
Top