iOS Question Map to Json problem with boolean value

StxTeam

Member
Licensed User
Hi,
in debug mode i have a problem in creation of a Json from Map

My code

B4X:
    WebApiAuthBase.Put("IsAdmin",False)
    WebApiAuthBase.Put("Roles",Null)
    WebApiAuthBase.Put("License",Null)
    WebApiAuthBase.Put("Modules",Null)
    WebApiAuthBase.Put("Auths",Null)
    WebApiAuthBase.Put("Factory",Null)
    WebApiAuthBase.Put("Module",Null)
    WebApiAuthBase.Put("Area",Null)
    WebApiAuthBase.Put("Geo",Null)
    WebApiAuthBase.Put("Version",Vers_AppCore_Code)
    WebApiAuthBase.Put("CallerType",1)

    Dim json As JSONGenerator
    json.Initialize(WebApiAuthBase)
    Log(json.ToString)

this code return this json:
{"IsAdmin":0,"CallerType":1,"Version":"1.8.6"}

but the right json should be:
{"IsAdmin":False,"CallerType":1,"Version":"1.8.6"}

The same code in B4a work fine with some difference, Json.ToString in B4a include also Null value.

I didn't test code in release mode.

Thanks everybody for a solution.
 

Semen Matusovskiy

Well-Known Member
Licensed User
I did not notice similar problem.
Meanwhile my program writes JSONs and (when reads). checks type of object

Your test works fine also (at least in current B4I release)
B4X:
   Dim WebApiAuthBase As Map
    WebApiAuthBase.Initialize    
    
    WebApiAuthBase.Put("Roles",     Null)
    WebApiAuthBase.Put("IsAdmin",   False)
    WebApiAuthBase.Put("License",  Null)
    WebApiAuthBase.Put("Modules",    Null)
    WebApiAuthBase.Put("Auths",     Null)
    WebApiAuthBase.Put("Factory",   Null)
    WebApiAuthBase.Put("Module",    Null)
    WebApiAuthBase.Put("Area",      Null)
    WebApiAuthBase.Put("Geo",       Null)
    WebApiAuthBase.Put("Version",   "Vers_AppCore_Code")
    WebApiAuthBase.Put("CallerType", 1)

    Dim jsonGenerator As JSONGenerator    
    jsonGenerator.Initialize (WebApiAuthBase)        
    Log (jsonGenerator.ToString)

Output:
{"IsAdmin":false,"CallerType":1,"Version":"Vers_AppCore_Code"}
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
Also working correctly here (B4I 6.00 in debug mode)
{"IsAdmin":False,"CallerType":1,...

Anyhow, if you parse the produced json into a Map and read again that field (which contains an integer) into a boolean, it will give True if the value is <>0 and false otherwise

Very dirty workaround if you need to deliver the JSON string with the correct 'true' and 'false' ?
B4X:
  Dim WebApiAuthBase As Map
    WebApiAuthBase.Initialize    
    
Dim myFalse as String = "myFalse"
Dim myTrue as String = "myTrue"

    WebApiAuthBase.Put("IsAdmin",   myFalse)
    WebApiAuthBase.Put("IsAdmin2",   myTrue)
    WebApiAuthBase.Put("Roles",     Null)
    WebApiAuthBase.Put("License",  Null)
    WebApiAuthBase.Put("Modules",    Null)
    WebApiAuthBase.Put("Auths",     Null)
    WebApiAuthBase.Put("Factory",   Null)
    WebApiAuthBase.Put("Module",    Null)
    WebApiAuthBase.Put("Area",      Null)
    WebApiAuthBase.Put("Geo",       Null)
    WebApiAuthBase.Put("Version",   "Vers_AppCore_Code")
    WebApiAuthBase.Put("CallerType", 1)

    Dim jsonGenerator As JSONGenerator    
    jsonGenerator.Initialize (WebApiAuthBase)      

   Log(jsonGenerator.ToString)
   Dim dirtyWorkaroundCorrectedString as String = jsonGenerator.ToString.Replace( $""myFalse""$, "false").Replace($""myTrue""$, "true")
  
   Log (dirtyWorkaroundCorrectedString)
 
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
In my program I do not use any workaround.
When I create a JSON, I write jsonGenerator.ToString to file.

Further I read a file (as string) and initialize jsonParser. Like here:
B4X:
    Dim WebApiAuthBase As Map
    WebApiAuthBase.Initialize    
    
    WebApiAuthBase.Put("Roles",     Null)
    WebApiAuthBase.Put("IsAdmin",   False)
    WebApiAuthBase.Put("License",  Null)
    WebApiAuthBase.Put("Modules",    Null)
    WebApiAuthBase.Put("Auths",     Null)
    WebApiAuthBase.Put("Factory",   Null)
    WebApiAuthBase.Put("Module",    Null)
    WebApiAuthBase.Put("Area",      Null)
    WebApiAuthBase.Put("Geo",       Null)
    WebApiAuthBase.Put("Version",   "Vers_AppCore_Code")
    WebApiAuthBase.Put("CallerType", 1)

    Dim jsonGenerator As JSONGenerator    
    jsonGenerator.Initialize (WebApiAuthBase)        
    Dim stringInput As String = jsonGenerator.ToString
    
    Dim jsonParser As JSONParser
    jsonParser.Initialize (stringInput)
    Dim root As Map = jsonParser.NextObject
    Dim IsAdmin As Object = root.Get("IsAdmin")
    If IsAdmin Is Int Then Log ("Int")
    If IsAdmin Is Boolean Then Log ("Boolean")

As you can see, IsAdmin remains Boolean. Probably, something happens if to save Map to file (instead of string).
 
Upvote 0

StxTeam

Member
Licensed User
My vers. B4I 6.30,

i send this json to a webserver, with wireshark i got the same result
{"IsAdmin":0,"CallerType":1,"Version":"1.8.6"}

I get this result by my test, if i brake code, in debug windows the map structure is right, and also log give me right as wireshark, but if i execute code without brake, i got the problem.

I will try in release.
 
Upvote 0

StxTeam

Member
Licensed User
I try it in release mode, but it doen't work, the same as debug mode.

I try to reproduce it in a small program.

I let you know soon.
 
Upvote 0

StxTeam

Member
Licensed User
Here my test project, same result.

But if i try to comment a line in sub "InizializeWebApiAuthBase" without clearing Project ("CTRL+P" ) it works fine.

Any idea?

Thanks everybody.
 

Attachments

  • TestJson.zip
    53.5 KB · Views: 185
Upvote 0

Semen Matusovskiy

Well-Known Member
Licensed User
Yes, strange. Try to add to Process_Globals
B4X:
Public Const myTrue  As Boolean = True
Public Const myFalse As Boolean = False

and replace False, True to myFalse, myTrue.
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
As I wrote, the underlying type system doesn't support real booleans. They are represented with numbers.

Not very nice but works:
B4X:
Sub Process_Globals
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page
    
    Private MyMap As Map
    Private JSONTrue = "~~~true~~~", JSONFalse = "~~~false~~~", JSONNull = "~~~null~~~" As String
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)
    MakeJson
End Sub

Sub MakeJson
    Dim JSON As JSONGenerator
    
    If MyMap.IsInitialized = False Then
        InizializeWebApiAuthBase
    End If
    
    JSON.Initialize(MyMap)
    Log(JSONToString(JSON))
End Sub

Sub JSONToString(jg As JSONGenerator) As String
    Return jg.ToPrettyString(4).Replace($""${JSONTrue}""$, "True").Replace($""${JSONFalse}""$, "False").Replace($""${JSONNull}""$, "Null")
End Sub

'Inizialize WebapiAuth base
Sub InizializeWebApiAuthBase
    
    MyMap.Initialize
    MyMap.Put("Culture","en-GB")
    MyMap.Put("IsLogged",JSONTrue)
    MyMap.Put("UserLogin",JSONNull)
    
    MyMap.Put("UserPK",JSONNull)

    MyMap.Put("IsAdmin",JSONFalse)
    MyMap.Put("Roles",JSONNull)
    MyMap.Put("License",JSONNull)
    MyMap.Put("Modules",JSONNull)
    MyMap.Put("Auths",JSONNull)
    MyMap.Put("Factory",JSONNull)
    MyMap.Put("Module",JSONNull)
    MyMap.Put("Area",JSONNull)
    MyMap.Put("Geo",JSONNull)
    MyMap.Put("Version","1.8.6")
    MyMap.Put("CallerType",1) 
End Sub
 
Upvote 0

StxTeam

Member
Licensed User
Thanks Erel it works. Do you thinks there'll be a solution in future, a nice solution ? ? Because our app must work with an IIS webapi and it doesn't accept 0 or 1 as boolean.
 
Upvote 0

AneeshJay

Member
Licensed User
Found the solution to this problem. It is only when adding a boolean value directly to a collection(list, map, etc.), the json serializer converts the boolean value to 0s and 1s. If the boolean value is set to a boolean variable and then added to a collection is then serialized correctly.

For example:
Dim mBool as Boolean = True
myMap.put("boolvalue", mBool)

Or:
mMap.put("booleanvalue", True.as(Boolean))

works perfectly.
 
Upvote 0
Top