Android Question Doubt Enter Json Data

JoséCarlos

Member
Licensed User
Android JSON tutorial made by Erel was given as an example the Json file below.
My question is if I can enter data in this file through the Application and return to using the file with this new data?
For example insert:

B4X:
{"value": "Delete", "onclick": "DeleteDoc()"}

B4X:
{"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}
 

drgottjr

Expert
Licensed User
Longtime User
here's 1 way:
B4X:
    Dim ajson As String = File.ReadString( File.DirAssets,"jason.txt")
    Log( ajson )
    
    Dim parser As JSONParser
    parser.Initialize( ajson )
    Dim mainmap As Map = parser.NextObject
    Dim secondmap As Map = mainmap.Get("menu")
    
    Dim id As String = secondmap.Get( "id" )
    Dim value As String = secondmap.Get( "File" )
    Dim popup As Map = secondmap.Get( "popup" )
    Dim menuitem As List = popup.Get("menuitem")
    
    ' CHANGE ID     
    ' OLD ID = "file"   NEW ID = "carlos"   
    Dim newid As String = "carlos"
    secondmap.Put( "id", newid )
    
        
    Dim generator As JSONGenerator
    generator.Initialize(mainmap)   ' replacing "file" with "carlos"
    Dim generatedstring As String = generator.ToPrettyString(2)
    Log( generatedstring )
    
    Dim rp As RuntimePermissions
    
    File.WriteString(rp.GetSafeDirDefaultExternal(""), "jason.txt", generatedstring)


note: if the file you read in is kept in dir.assets, you can't save it back to dir.assets. it has to go elsewhere, eg, dir.internal or safedirdefaultexternal. in other words, if you must keep the same file and the original file is in dir.assets, you have to first copy it to dir.internal (or safedirdefaultexternal) before reading it into the app. otherwise, you will have 2 copies of the file in 2 different locations: the original and the changed version. i hope this is clear.
 

Attachments

  • json.png
    json.png
    44.9 KB · Views: 172
Upvote 0

JoséCarlos

Member
Licensed User
Thank you very much for your attention.
What I wanted was to enter data, not pass it on as was the case in your example.
What I wanted is to stay like this, inserted in that fourth item "menuitem":

B4X:
{"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
      {"value": "Delete", "onclick": "DeleteDoc()"}
    ]
  }
}}


I don't know if it's possible.
Hugs.
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
same story. the elements of the list are just maps (json objects). create a new map element and add it to the list.
B4X:
    Dim ajson As String = File.ReadString( File.DirAssets,"jason.txt")
    Log( ajson )
    
    Dim parser As JSONParser
    parser.Initialize( ajson )
    Dim mainmap As Map = parser.NextObject
    Dim secondmap As Map = mainmap.Get("menu")
    
    Dim id As String = secondmap.Get( "id" )
    Dim value As String = secondmap.Get( "File" )
    Dim popup As Map = secondmap.Get( "popup" )
    Dim menuitem As List = popup.Get("menuitem")
    
    ' CHANGE ID     
    ' OLD ID = "file"   NEW ID = "carlos"   
    Dim newid As String = "carlos"
    secondmap.Put( "id", newid )
    
    ' ALSO ADD ITEM TO LIST
    Dim newmap As Map
    newmap.Initialize
    ' {"value": "Delete", "onclick": "DeleteFile()"}
    newmap.Put("value", "Delete")
    newmap.Put("onclick", "DeleteFile()")
    menuitem.Add( newmap )
        
    Dim generator As JSONGenerator
    generator.Initialize(mainmap)   ' replacing "file" with "carlos"
    Dim generatedstring As String = generator.ToPrettyString(2)
    Log( generatedstring )
    
    Dim rp As RuntimePermissions
    
    File.WriteString(rp.GetSafeDirDefaultExternal(""), "jason.txt", generatedstring)

once you have read in the menuitem list, it's just a regular list. add, delete, edit items in/to the list:
B4X:
    Dim newmap As Map
    newmap.Initialize
    ' {"value": "Delete", "onclick": "DeleteFile()"}
    newmap.Put("value", "Delete")
    newmap.Put("onclick", "DeleteFile()")
    ' then add the new item to the list
    menuitem.Add( newmap )
 

Attachments

  • jcarlos.png
    jcarlos.png
    49.5 KB · Views: 131
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
For example insert:
sorry:
correction

B4X:
    Dim t As String = $"
                    {"menu": {
                      "id": "file",
                      "value": "File",
                      "popup": {
                        "menuitem": [
                          {"value": "New", "onclick": "CreateNewDoc()"},
                          {"value": "Open", "onclick": "OpenDoc()"},
                          {"value": "Close", "onclick": "CloseDoc()"}
                        ]
                      }
                    }}
                    "$
  
    Dim JsonMap As Map = t.As(JSON).ToMap.Get("menu").As(Map) 'ignore
    JsonMap.Remove("popup")
  
    Dim menuitem As List = t.As(JSON).ToMap.Get("menu").As(Map).Get("popup").As(Map).Get("menuitem").As(List) 'ignore
    menuitem.Add(CreateMap("value": "Delete", "onclick": "DeleteDoc()"))
  
    Dim popup As Map =  CreateMap("menuitem" : menuitem)
    JsonMap.Put("popup", popup)
  
    JsonMap = CreateMap("menu": JsonMap)
    Dim s As String = JsonMap.As(JSON).ToString
    Log(s)

result:
JSON:
{
    "menu": {
        "popup": {
            "menuitem": [
                {
                    "onclick": "CreateNewDoc()",
                    "value": "New"
                },
                {
                    "onclick": "OpenDoc()",
                    "value": "Open"
                },
                {
                    "onclick": "CloseDoc()",
                    "value": "Close"
                },
                {
                    "onclick": "DeleteDoc()",
                    "value": "Delete"
                }
            ]
        },
        "id": "file",
        "value": "File"
    }
}
 
Upvote 0

JoséCarlos

Member
Licensed User
Good afternoon.
Thank you drgottjr!
That's exactly what I wanted, for a beginner like me in B4A, his explanations were very enlightening.
Hugs and again Thank you.
 
Upvote 0

Peter Simpson

Expert
Licensed User
Longtime User
Hello @JoséCarlos
Here is another example for you to learn from ;)

B4X:
    Dim JS As String = $"
                    {"menu": {
                      "id": "file",
                      "value": "File",
                      "popup": {
                        "menuitem": [
                          {"value": "New", "onclick": "CreateNewDoc()"},
                          {"value": "Open", "onclick": "OpenDoc()"},
                          {"value": "Close", "onclick": "CloseDoc()"}
                        ]
                      }
                    }}
                    "$

    Dim LstMenuItem As List = JS.As(JSON).ToMap.Get("menu").As(Map).Get("popup").As(Map).Get("menuitem") 'Ignore - Get menu items
        LstMenuItem.Add(CreateMap("value": "Delete", "onclick": "DeleteDoc()")) 'Add menu items to the list

    Dim MapMenu As Map = JS.As(JSON).ToMap.Get("menu") 'Ignore - Get the menu from the JSON string as a map
        MapMenu.Put("popup", CreateMap("menuitem" : LstMenuItem)) 'Add the updated menu items to popup and replace the original popup values in the map
        MapMenu = CreateMap("menu": MapMenu) 'Recreate the new menu map ready to be used

    Log(MapMenu.As(JSON).ToString)
  1. There's no need to use remove popup key as it is in a map. Using put popup key will overwrite the current popup value in the map
  2. To keep the code easier to read, you can just create the new menu map over the previously declared map, thus less code

Gives you this, the exact same results as @oparra
JSON:
{
    "menu": {
        "popup": {
            "menuitem": [
                {
                    "onclick": "CreateNewDoc()",
                    "value": "New"
                },
                {
                    "onclick": "OpenDoc()",
                    "value": "Open"
                },
                {
                    "onclick": "CloseDoc()",
                    "value": "Close"
                },
                {
                    "onclick": "DeleteDoc()",
                    "value": "Delete"
                }
            ]
        },
        "id": "file",
        "value": "File"
    }
}

There are so many ways to get the same results.


Enjoy...
 
Last edited:
Upvote 0
Top