Android Question Issue with JSON Parsing

techknight

Well-Known Member
Licensed User
Longtime User
Having a slight problem with JSON parsing, I am sure I am making a mistake somewhere but I am entirely not sure what.

Here is my JSON Payload:
{"GameOptions":{"GameOptionsClockPreset1":"","GameOptionsClockPreset2":"","GameOptionsClockPreset3":"","GameOptionsHornEnable":true,"GameOptionsScreen1":false,"GameOptionsScreen2":true,"GameOptionsSport":2,"GameOptionsLightingEnable":true,"GameOptionsRetainLighting":true}}

Which gets parsed down to this:
{GameOptionsClockPreset1=, GameOptionsClockPreset2=, GameOptionsClockPreset3=, GameOptionsHornEnable=true, GameOptionsScreen1=false, GameOptionsScreen2=true, GameOptionsSport=2, GameOptionsLightingEnable=true, GameOptionsRetainLighting=true}

From this code snippet:
B4X:
Type ScoreCommand (Command As String, Data As Object) 'Packet sent between main device and stat remote device        

    'The JSON packet should contain the ScoreCommand Object in text format, which is the Command itself, and the Value.
    JSON.Initialize(BytesToString(Buffer, 0, Buffer.Length, "UTF-8"))
    Dim jRoot As Map = JSON.NextObject
    If jRoot.Size = 1 Then         'Maximum and minimum of 1 item in the map. The top object is always a ScoreCommand type.
'        Dim ScoreCommandMap As Map = jRoot.Get(0)        'Only the first element of the array is necessary, and should contain our scorecommand.
        Dim DataPacket As ScoreCommand
        DataPacket.Initialize
        DataPacket.Command = jRoot.GetKeyAt(0)
        DataPacket.Data = jRoot.GetValueAt(0)
    Else    'Return on failure
        Return
    End If

Notice, sometimes there are empty strings when things arent set by the sender.

The specific code to parse it back into a Map and custom object is this:

B4X:
    Type GameOptionsData(HornEnable As Boolean, Screen1 As Boolean, Screen2 As Boolean, ClockPreset1 As String, ClockPreset2 As String, ClockPreset3 As String, Sport As Int, LightingEnable As Boolean, RetainLighting As Boolean)
Public GameOptions As GameOptionsData


            Try
                Dim JSON As JSONParser
                JSON.Initialize(DataPacket.Data)
                Dim ScoreData As Map = JSON.NextObject
                Common.MapToGameOptions(ScoreData, GameOptions)         
            Catch
                Log(LastException)
            End Try

'Convert Map to Game Options
Sub MapToGameOptions(V2Data As Map, GameOptions As GameOptionsData)
    If V2Data.ContainsKey("GameOptionsClockPreset1") Then GameOptions.ClockPreset1 = V2Data.Get("GameOptionsClockPreset1")
    If V2Data.ContainsKey("GameOptionsClockPreset2") Then GameOptions.ClockPreset2 = V2Data.Get("GameOptionsClockPreset2")
    If V2Data.ContainsKey("GameOptionsClockPreset3") Then GameOptions.ClockPreset3 = V2Data.Get("GameOptionsClockPreset3")
    If V2Data.ContainsKey("GameOptionsHornEnable") Then GameOptions.HornEnable = V2Data.Get("GameOptionsHornEnable")
    If V2Data.ContainsKey("GameOptionsScreen1") Then GameOptions.Screen1 = V2Data.Get("GameOptionsScreen1")
    If V2Data.ContainsKey("GameOptionsScreen2") Then GameOptions.Screen2 = V2Data.Get("GameOptionsScreen2")
    If V2Data.ContainsKey("GameOptionsSport") Then GameOptions.Sport = V2Data.Get("GameOptionsSport")
    If V2Data.ContainsKey("GameOptionsLightingEnable") Then GameOptions.LightingEnable = V2Data.Get("GameOptionsLightingEnable")
    If V2Data.ContainsKey("GameOptionsRetainLighting") Then GameOptions.RetainLighting = V2Data.Get("GameOptionsRetainLighting")
End Sub

The trouble is, I am getting this error:
(JSONException) org.json.JSONException: Expected literal value at character 25 of {GameOptionsClockPreset1=, GameOptionsClockPreset2=, GameOptionsClockPreset3=, GameOptionsHornEnable=true, GameOptionsScreen1=true, GameOptionsScreen2=false, GameOptionsSport=2, GameOptionsLightingEnable=true, GameOptionsRetainLighting=true}

I assume its due to the empty strings which shouldnt be an issue as they are supposed to be blank sometimes, almost as if the quotes are being stripped out of the payload.

Not sure where to go from here. Thanks!
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
Here is my JSON Payload:
{"GameOptions":{"GameOptionsClockPreset1":"

The payload contains one Map.

The only key in it is GameOptions.
GameOptions is another Map.

I can´t see how you are getting the inner map to get the different values like GameOptionsClockPreset1 or GameOptionsSport (ect)

In MapToGameOptions get the GameOptions and use the inner map then...

B4X:
Dim V2DataInnerMap as Map = V2Data.Get("GameOptions")
[..]
If V2DataInnerMap.ContainsKey("GameOptionsClockPreset1") Then GameOptions.ClockPreset1 = V2DataInnerMap.Get("GameOptionsClockPreset1")
[ect]
 
Last edited:
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
I may not be following what youre saying but ill try to explain:

Initial packet contains a map which its value is another map. (sometimes but in this case, it is) I break the first map out into a customtype of Command and Data. Command is used in a big select case statement and in this case it's ScoreData.

The Data is the other map of key/value pairs.

Thats why I have two codeblocks posted. 1st block gets the value which contains another map

second block is supposed to parse that value of the 1st map as a 2nd map. Thats where its breaking on this particualr one.
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
The payload contains one Map.

The only key in it is GameOptions.
GameOptions is another Map.

I can´t see how you are getting the inner map to get the different values like GameOptionsClockPreset1 or GameOptionsSport (ect)

In MapToGameOptions get the GameOptions and use the inner map then...

B4X:
Dim V2DataInnerMap as Map = V2Data.Get("GameOptions")
[..]
If V2DataInnerMap.ContainsKey("GameOptionsClockPreset1") Then GameOptions.ClockPreset1 = V2DataInnerMap.Get("GameOptionsClockPreset1")
[ect]

Yeah that opened my eyes a bit. I forgot, the value was also being unwrapped during the first JSON parse, for some reason I was thinking it was still encoded in JSON but it was not.
 
Upvote 0

teddybear

Well-Known Member
Licensed User
(JSONException) org.json.JSONException: Expected literal value at character 25 of {GameOptionsClockPreset1=, GameOptionsClockPreset2=, GameOptionsClockPreset3=, GameOptionsHornEnable=true, GameOptionsScreen1=true, GameOptionsScreen2=false, GameOptionsSport=2, GameOptionsLightingEnable=true, GameOptionsRetainLighting=true}
It is obvious that the error is in the presence of null values in the json string
B4X:
            Try
                Dim JSON As JSONParser
                JSON.Initialize(DataPacket.Data)

                Dim ScoreData As Map = JSON.NextObject
                Common.MapToGameOptions(ScoreData, GameOptions)    
            Catch
                Log(LastException)
            End Try
It is incorrect to parse the DataPacket.Data. it is already a map, but you are forcing it to be cast as a string. an empty string value becomes a null value
You should pass directly the DataPacket.Data to MapToGameOptions
B4X:
            Try

                'Dim JSON As JSONParser

                'JSON.Initialize(DataPacket.Data)

                'Dim ScoreData As Map = JSON.NextObject

                Common.MapToGameOptions(DataPacket.Data, GameOptions)    

            Catch

                Log(LastException)

            End Try
 
Last edited:
Upvote 0
Top