Android Question Error : JSON Array expected

khwarizmi

Active Member
Licensed User
Longtime User
Hi all

am working on an online database application.
I have a table contains only phone_number and ID

I use this code to get all the phone numbers and IDs and put them into 2 lists (ls1 and ls2) :

B4X:
Sub check_for_all_phones_and_IDs
 
    Dim GetPersons As HttpJob
    GetPersons.Initialize("GetP", Me)
    GetPersons.download2("http://newg.com.sd/b4atest/users/checkphone.php", Array As String ("id", "phone_num"))
 
End Sub

Sub JobDone(Job As HttpJob)

    ProgressDialogHide
 
    If Job.Success Then
        Dim res As String
        res = Job.GetString
        Dim parser As JSONParser
        parser.Initialize(res)
        ls1.Clear
 
        Select Job.JobName
 
            Case "GetP"
                Dim ListOfPersons As List
                Dim PersonName As String
                Dim PersonAge As String
    
            ListOfPersons = parser.NextArray 'returns a list with maps
        
                
 
                If ListOfPersons.Size=0 Then
                    ' no results
                Else
 
                    For i = 0 To ListOfPersons.Size - 1
                        Dim Person As Map
                        Person = ListOfPersons.Get(i)
                        PersonAge = Person.Get("phone_number")
                        PersonName = Person.Get("id")
                        ls1.Add(PersonAge)
                        ls2.Add(PersonName)
                    Next
 
                End If
 
            Case "InsertP"
                '     Log(Job.GetString)
 
            Case "dltID"
        End Select
 
    Else
        ToastMessageShow("Error: " & Job.ErrorMessage, True)
    End If

    Job.Release

End Sub

the code is working very well when there is fields in the table, but when the table is empty I get this error :

java.lang.RuntimeException: JSON Array expected.

thanks in advance
 

lemonisdead

Well-Known Member
Licensed User
Longtime User
Hello,
Seems to be luckily the normal behavior : when Job is successful, you get the returned string and send it to parser. But parser was expecting something it could parse. And you probably have only Null or "" in res.
So, you only have to submit res to parser if, for example, res size is greater than 0 (or 1).
Hope it could help (I am not on the PC so I can not provide some code). Just don't send data to parser when you didn't got something it could parse
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Please re-read @lemonisdead's answer. JSONParser is very unforgiving when you pass it invalid data. If your site does not return a valid JSON array (a string starting with [ and ending with ]), the .NextArray will bomb, since there is no NextArray. It is up to you to ensure that you are feeding JSONParser valid information. Why don't you log your variable res or Job.GetString to see what is going on (what values are being returned).
 
Upvote 0

khwarizmi

Active Member
Licensed User
Longtime User
thanks ..

when I wrote :

Log(res.Length)
Log(res)

then answer was:
8
no data
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
then answer was:
8
no data
So
1) If you are in control of the server side (you did say
I have a table contains only phone_number and ID
), change the server code to return consistent JSON data (in this case an empty array instead of the text "no data").
Or
2) Change your client code to check for "no data" as your return value for GetString before parsing GetString as JSON data.
 
Upvote 0

cirollo

Active Member
Licensed User
Longtime User
I have a similar problem,

my ws returns this jSON:

{"output":{"1":{"USERWEB":"10028 ","PWDUWEB":"WEBBAACI ","DBNAME":"FS_SCHOOL"}}}

I've tried an online parser (JSONLint) and is signed as valid, but i get the following error.....

B4X:
Logger connesso a:  HUAWEI PRA-LX1
--------- beginning of system
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
JobName = Job1, Success = true
Back from Job:Job1
Response from server: {"output":{"1":{"USERWEB":"10028               ","PWDUWEB":"WEBBAACI            ","DBNAME":"FS_SCHOOL"}}}
{"output":{"1":{"USERWEB":"10028               ","PWDUWEB":"WEBBAACI            ","DBNAME":"FS_SCHOOL"}}}
Error occurred on line: 198 (Main)
java.lang.RuntimeException: JSON Array expected.
   at anywheresoftware.b4a.objects.collections.JSONParser.NextArray(JSONParser.java:62)
   at java.lang.reflect.Method.invoke(Native Method)
   at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:733)
   at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:352)
   at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
   at java.lang.reflect.Method.invoke(Native Method)
   at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
   at anywheresoftware.b4a.BA$2.run(BA.java:365)
   at android.os.Handler.handleCallback(Handler.java:808)
   at android.os.Handler.dispatchMessage(Handler.java:101)
   at android.os.Looper.loop(Looper.java:166)
   at android.app.ActivityThread.main(ActivityThread.java:7425)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
 
Upvote 0

Douglas Farias

Expert
Licensed User
Longtime User
I have a similar problem,

my ws returns this jSON:

{"output":{"1":{"USERWEB":"10028 ","PWDUWEB":"WEBBAACI ","DBNAME":"FS_SCHOOL"}}}

I've tried an online parser (JSONLint) and is signed as valid, but i get the following error.....

B4X:
Logger connesso a:  HUAWEI PRA-LX1
--------- beginning of system
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (httputils2service) Create ***
** Service (httputils2service) Start **
JobName = Job1, Success = true
Back from Job:Job1
Response from server: {"output":{"1":{"USERWEB":"10028               ","PWDUWEB":"WEBBAACI            ","DBNAME":"FS_SCHOOL"}}}
{"output":{"1":{"USERWEB":"10028               ","PWDUWEB":"WEBBAACI            ","DBNAME":"FS_SCHOOL"}}}
Error occurred on line: 198 (Main)
java.lang.RuntimeException: JSON Array expected.
   at anywheresoftware.b4a.objects.collections.JSONParser.NextArray(JSONParser.java:62)
   at java.lang.reflect.Method.invoke(Native Method)
   at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:733)
   at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:352)
   at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
   at java.lang.reflect.Method.invoke(Native Method)
   at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
   at anywheresoftware.b4a.BA$2.run(BA.java:365)
   at android.os.Handler.handleCallback(Handler.java:808)
   at android.os.Handler.dispatchMessage(Handler.java:101)
   at android.os.Looper.loop(Looper.java:166)
   at android.app.ActivityThread.main(ActivityThread.java:7425)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
B4X:
im parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim output As Map = root.Get("output")
Dim 1 As Map = output.Get("1")
Dim PWDUWEB As String = 1.Get("PWDUWEB")
Dim DBNAME As String = 1.Get("DBNAME")
Dim USERWEB As String = 1.Get("USERWEB")
 
Upvote 0

cirollo

Active Member
Licensed User
Longtime User
ok, you're right this is my b4a code:

B4X:
Sub JobDone (Job As HttpJob)
   Log("JobName = " & Job.JobName & ", Success = " & Job.Success)
   Log(Job.ErrorMessage)
   If Job.Success = True Then
       Dim res As String
       res = "["&Job.GetString&"]"
       Log("Back from Job:" & Job.JobName )
       Log("Response from server: " & res)
       Log(Job.GetString)
       ' facciamo il parsing del json ricevuto
       Dim parser As JSONParser
       parser.Initialize(res)
       Dim root As List = parser.NextArray
       For Each colroot As Map In root
           Dim USERWEB As String = colroot.Get("USERWEB")
           Dim PWDUWEB As String = colroot.Get("PWDUWEB")
           Dim DBNAME As String = colroot.Get("DBNAME")
          
           Log("USERWEB = "&USERWEB.Trim&" - PWDUWEB = "&PWDUWEB.Trim&" - DBNAME = "&DBNAME.Trim)
   Else
       Log("Error: " & Job.ErrorMessage)
   '   ToastMessageShow("Error: " & Job.ErrorMessage, True)
       Msgbox(Job.ErrorMessage,"Errore")
       ok_procedi = False
   End If
   Job.Release
End Sub

now, after I put the [] to my JSON:
res = "["&Job.GetString&"]"
I'm not getting the error of JSON array expected, but I'm getting all the values (USERWEB,PWDUWEB and DBNAME) as null....

maybe I'm using too much quotes?????

my JSON returned from WS

{"output":{"1":{"USERWEB":"10028 ","PWDUWEB":"WEBBAACI ","DBNAME":"FS_SCHOOL"}}}
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
maybe I'm using too much quotes?????
yes

See answer #11 above.

B4X:
Dim res As String = job.getstring
dim parser As JSONParser
parser.Initialize(res)
Dim root As Map = parser.NextObject
Dim output As Map = root.Get("output")
Dim map1 As Map = output.Get("1")
Dim PWDUWEB As String = 1.Get("PWDUWEB")
Dim DBNAME As String = 1.Get("DBNAME")
Dim USERWEB As String = 1.Get("USERWEB")
 Log("USERWEB = "&USERWEB.Trim&" - PWDUWEB = "&PWDUWEB.Trim&" - DBNAME = "&DBNAME.Trim)

You ws return a invalid json. It is using 1 as a fieldname
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
for a quick result you should change
{"output":{"1":{"USERWEB":"10028 ","PWDUWEB":"WEBBAACI ","DBNAME":"FS_SCHOOL"}}}
to output only one result as before
{"output":{"Record":{"RecNo":"1","USERWEB":"10028 ","PWDUWEB":"WEBBAACI ","DBNAME":"FS_SCHOOL"}}}

B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim output As Map = root.Get("output")
Dim Record As Map = output.Get("Record")
Dim PWDUWEB As String = Record.Get("PWDUWEB")
Dim RecNo As String = Record.Get("RecNo")
Dim DBNAME As String = Record.Get("DBNAME")
Dim USERWEB As String = Record.Get("USERWEB")
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
java.lang.RuntimeException: JSON Array expected.
at anywheresoftware.b4a.objects.collections.JSONParser.NextArray(JSONParser.java:62)
For this error, please see my answer in post #4 under this thread.
I'm not getting the error of JSON array expected, but I'm getting all the values (USERWEB,PWDUWEB and DBNAME) as null....
Why don't you use JSONTree to help you parse your modified JSON structure instead of guessing. JSONTree: http://basic4ppc.com:51042/json/index.html
Using this tool and your modified JSON structure of
B4X:
[{"output":{"1":{"USERWEB":"10028 ","PWDUWEB":"WEBBAACI ","DBNAME":"FS_SCHOOL"}}}]
the code output will be:
B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As List = parser.NextArray
For Each colroot As Map In root
 Dim output As Map = colroot.Get("output")
 Dim 1 As Map = output.Get("1")
 Dim PWDUWEB As String = 1.Get("PWDUWEB")
 Dim DBNAME As String = 1.Get("DBNAME")
 Dim USERWEB As String = 1.Get("USERWEB")
Next
1 is a record id I put on my JSON, I can put anything else, or.....how can I manage multiple records?
Don't make the record id the key part of the key/value pairs of a JSON record. The key part should be fixed, the value part usually is not. One way may be:
B4X:
[{"output":"1", "USERWEB":"10028 ","PWDUWEB":"WEBBAACI ","DBNAME":"FS_SCHOOL"},
{"output":"2", "USERWEB":"10028 ","PWDUWEB":"WEBBAACI ","DBNAME":"FS_SCHOOL"}]
Which can be accessed via
B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As List = parser.NextArray
For Each colroot As Map In root
 Dim output As String = colroot.Get("output")
 Dim PWDUWEB As String = colroot.Get("PWDUWEB")
 Dim DBNAME As String = colroot.Get("DBNAME")
 Dim USERWEB As String = colroot.Get("USERWEB")
Next
Please note that I'm just guessing at the structure you are trying to create. The key"output" now contains your record id's. Again, use JSONTree to create valid JSON structures and to create code that accesses these structures.
Another option
B4X:
{"output": 
   [
      {"recordID": "1", "USERWEB":"10028 ","PWDUWEB":"WEBBAACI ","DBNAME":"FS_SCHOOL"},
      {"recordID": "2", "USERWEB":"10028 ","PWDUWEB":"WEBBAACI ","DBNAME":"FS_SCHOOL"}
   ]
}
Access code:
B4X:
Dim parser As JSONParser
parser.Initialize(<text>)
Dim root As Map = parser.NextObject
Dim output As List = root.Get("output")
For Each coloutput As Map In output
 Dim recordID As String = coloutput.Get("recordID")
 Dim PWDUWEB As String = coloutput.Get("PWDUWEB")
 Dim DBNAME As String = coloutput.Get("DBNAME")
 Dim USERWEB As String = coloutput.Get("USERWEB")
Next
 
Upvote 0
Top