Android Question Create MAP (as map)

Rusty

Well-Known Member
Licensed User
Longtime User
I am trying to create a JSON file and can't seem to grasp how to create the appropriate map to add.
An example would be:
Person
First Name: Fred
Last Name: Jones
Address
-->Address1: 123 Elm
-->Address2: Apt A
-->City: Chicago
-->State: Illinois
-->Country: USA
Phone
-->Home: (303) 321-3321
-->Office: (303) 444-4321
...etc.
Note: (-->) is used to indicate the subordination of data i.e. phone --> Home:
I know how to dimension a Map and use CreateMap to create it, but how to embed data into a "complex" map.
Can anyone please advise me?
Thanks in advance,
Rusty
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
B4X:
Dim jg As JSONGenerator
Dim m As Map = CreateMap("Person": CreateMap( _
                       "First Name": "Fred", _
                       "Last Name": "Jones", _
                       "Address": CreateMap( _
                           "Adddress1": "123 Elm", _
                           "City": "Chicago"), _
                       "Phone": CreateMap( _
                           "Home": "12312321") _
                       ))
jg.Initialize(m)
Log(jg.ToPrettyString(4))
 
Upvote 0

Rusty

Well-Known Member
Licensed User
Longtime User
Ok, Creating the map is going well, however, retrieving the values of arrays of maps is not working quite right.
I have used the JSON tree example to evaluate the JSON and have copied and tried to use the generated code to get the map/key/values and the simple part of the JSON parses just fine. It's when I get to a "more complex" array of maps that things fall apart.
[{
"Questions": [{
"Question0": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 0"
}
},
{
"Question1": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 1"
}
}]
}]]
Generates the following code to parse the Question:
B4X:
dim JSONString as string = File.ReadString(File.DirRootExternal & " …
Dim parser As JSONParser
parser.Initialize(JSONString)
Dim root As List = parser.NextArray
For Each colroot As Map In root
 Dim Questions As List = colroot.Get("Questions") <------<<< This line generated the below error
 For Each colQuestions As Map In Questions
  Dim Question0 As Map = colQuestions.Get("Question0")
  Dim Answers As Map = Question0.Get("Answers")
  Dim Answer4 As Int = Answers.Get("Answer4")
  Dim Answer2 As Int = Answers.Get("Answer2")
  Dim Answer3 As Int = Answers.Get("Answer3")
  Dim Answer0 As Int = Answers.Get("Answer0")
  Dim Answer1 As Int = Answers.Get("Answer1")
  Dim Text As String = Question0.Get("Text")
 Next
Next

When I run this code I get:
(Exception) java.lang.Exception: java.lang.ClassCastException: java.util.ArrayList cannot be cast to anywheresoftware.b4a.objects.collections.Map$MyMap

I have tried many, many (bad) ideas and continue to fail on this.
Any advice is appreciated. :)
Thanks,
Rusty
 
Last edited:
Upvote 0

MarkusR

Well-Known Member
Licensed User
Longtime User
did you used this code with this line? <text> should be a variable as string with json data
B4X:
parser.Initialize(<text>)
 
Upvote 0

Rusty

Well-Known Member
Licensed User
Longtime User
No, sorry, I use JSONString which is the actual JSON string text.
I've updated my first post.
Thanks :)
 
Upvote 0

MarkusR

Well-Known Member
Licensed User
Longtime User
the problem was here: colQuestions.Get("Question0")
if you do not access by key you can also use the name "Question" again for each Question in the json source, means without index.

B4X:
Sub Test
 
    Dim JSONString As String = File.ReadString(File.DirAssets,"read.txt")
    Dim parser As JSONParser
    parser.Initialize(JSONString)
    Dim root As List = parser.NextArray
    For Each colroot As Map In root
        Dim Questions As List = colroot.Get("Questions") '<------<<< This line generated the below error
        Dim q As Int =0
        For Each colQuestions As Map In Questions
            Dim QuestionX As Map = colQuestions.Get("Question" & q)
            Dim Text As String = QuestionX.Get("Text")
            Log(Text)
            Dim Answers As Map = QuestionX.Get("Answers")
            Dim Answer4 As Int = Answers.Get("Answer4")
            Dim Answer2 As Int = Answers.Get("Answer2")
            Dim Answer3 As Int = Answers.Get("Answer3")
            Dim Answer0 As Int = Answers.Get("Answer0")
            Dim Answer1 As Int = Answers.Get("Answer1")
            Log(Answer0)
            Log(Answer1)
            Log(Answer2)
            Log(Answer3)
            Log(Answer4)       
            q=q+1
        Next
    Next
    
End Sub
 
Last edited:
Upvote 0

Rusty

Well-Known Member
Licensed User
Longtime User
Ok, Markus is a big help in parsing the above JSON.
I've added "Person" information to the top of the JSON and now the code doesn't work again...
[{
"Organization": {
"id": "ABC",
"Status": "Complete",
"Authored": "2018-01-15T21:34:46Z",
"facility": "ABC location",
"Group": "ThisGroup"
}
},
{
"Person": {
"LastName": "Jones",
"DOB": "09/01/2018",
"FirstName": "Fred"
}
},
{
"Address": {
"Country": "USA",
"State": "Colorado",
"Address2": "Apt. A",
"City": "Denver",
"Address1": "123 Elm"
}
},
[{
"Questions": [{
"Question0": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 0"
}
},
{
"Question1": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 1"
}
},
{
"Question2": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 2"
}
},
{
"Question3": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 3"
}
},
{
"Question4": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 4"
}
},
{
"Question5": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 5"
}
},
{
"Question6": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 6"
}
},
{
"Question7": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 7"
}
},
{
"Question8": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 8"
}
},
{
"Question9": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 9"
}
},
{
"Question10": {
"Answers": {
"Answer1": 1,
"Answer0": 0,
"Answer3": 3,
"Answer2": 2,
"Answer4": 4
},
"Text": "Question Text 10"
}
}]
}]]

When I try to parse this, it dies again...argh!
Sorry I'm not getting this, but I do appreciate the help.

B4X:
Dim parser As JSONParser
    parser.Initialize(JSONGenerator.ToString)
    Dim root As List = parser.NextArray
    For Each colroot As Map In root
        If colroot Is Map Then
            Dim O As Map = colroot.Get("Organization")
            If O.IsInitialized Then
                Dim S As String = O.Get("Status")
                Dim G As String = O.Get("Group")
                Dim idx As String = O.Get("id")
                Dim f As String = O.Get("facility")
                Dim A As String = O.Get("Authored")
            Else
                Dim adr As Map = colroot.Get("Address")
                If adr.IsInitialized Then
                    Dim A As String = adr.Get("Address1")
                Else
                    Dim pers As Map = colroot.Get("Person")
                    Dim ln As String = pers.Get("LastName")
                End If
            End If
        Else
            'HERE I CAN'T FIGURE OUT HOW TO PARSE THE QUESTIONS/ANSWERS PART
        End If
    Next
Rusty
 
Last edited:
Upvote 0

MarkusR

Well-Known Member
Licensed User
Longtime User
the problem is here
For Each colroot As Map In root
u have 3 maps but then comes a list

B4X:
    For Each colroot As Object In root
        If colroot Is Map Then
            Log(colroot Is Map)
            Dim mymap As Map = colroot
        End If
        If colroot Is List Then
            Log(colroot Is List)
            Dim mylist As List = colroot
            Log(mylist.Size)
        End If
    Next

ToPrettyString for log :)
B4X:
    Dim root As List = parser.NextArray

    Dim j As JSONGenerator
    j.Initialize2(root)
    Log(j.ToPrettyString(4))
 
Upvote 0

Rusty

Well-Known Member
Licensed User
Longtime User
Thanks! Combining your first example with the second and finding more MAP/ARRAY differences, I finally got it parsing correctly!!
 
Upvote 0
Top