TypeMismatchException with Xojo.Data.ParseJSON

I’m using the JSON format for files used in one of my apps, and although Xojo.Data.GenerateJSON is able to properly create the Text from the Dictionary, it is unable to parse the JSON it creates and return my dictionary. The relevant code from my app is:
This is where the JSON text representation is created and saved:

[code]Sub Save()
dim json as new xojo.Core.Dictionary
json.Value(“loginID”) = loginID
json.Value(“Name”) = Name
json.Value(“TeamNumber”) = TeamNumber
json.Value(“Section”) = Section
json.Value(“Time”) = Time

dim json2() as xojo.Core.Dictionary
dim tmp as xojo.Core.Dictionary
for i as Integer = 0 to 2
tmp = new xojo.core.Dictionary
tmp.Value(“Name”) = teamMembers(i)
tmp.Value(“loginID”) = teamLoginIDs(i)
json2.Append tmp
Next

json.Value(“team”) = xojo.data.GenerateJSON(json2)

//snipped code that saves to a file
End Sub[/code]

The code to parse the JSON text representation:

[code]Protected Sub Constructor()
//snipped code to read in the text into the variable “data as text”

dim json as xojo.Core.Dictionary = xojo.data.ParseJSON(data)

loginID = json.Value(“loginID”)
Name = json.Value(“Name”)
TeamNumber = json.Value(“TeamNumber”)
Section = json.Value(“Section”)
Time = json.Value(“Time”)

dim tmpStr as Text = json.Value(“team”)
dim json2() as xojo.Core.Dictionary = xojo.data.ParseJSON(tmpStr) //Type mismatch exception here, even though tmpStr matches what is created earlier
for i as Integer = 0 to 2
teamMembers.Append json2(i).Value(“Name”)
teamLoginIDs.Append json2(i).Value(“loginID”)
Next
End Sub[/code]

Is there something that I am doing wrong, or is this a limitation of Xojo.Data.ParseJSON?

Thanks for your help,
Jason

There’s no need to call ParseJSON a second time in your line that generates the type mismatch error. Instead:

dim json2() as auto = json.Value("team")

And you can delete the line above that creates tmpStr.

I’m not sure that’s right. The value of tmpStr which equals json.Value("team") is

[{"loginID":"*****","Name":"*****"},{"loginID":"*****","Name":"*****"},{"loginID":"*****","Name":"*****"}]

which is still a JSON string. When creating the JSON object in the save method I create the array of dictionaries, generate the JSON of that and store it in json.Value("team") then generate the JSON for json.

It works for me and my whole app reads JSON results from web services. But looking at this blog post from Paul it seems that you might just be able to dim json2 as dictionary instead of auto.

Also when saving an array of JSON within other JSON, I don’t call GenerateJSON for the array and again for the container. I just call it once for the container and it generates the JSON for the container (root) dictionary plus any sub-dictionaries and arrays of dictionaries. So maybe check that your JSON is valid too; there are many free online JSON validators.

Right, but shouldn’t it be an array of dictionaries since I passed an array of dictionaries when I was generating the JSON? Maybe I’m approaching this wrong and shouldn’t convert the array of dictionaries into JSON before storing it, but instead just make json.Value("team") = json2?

I’ve got to run (literally…meeting my running trainer in 2 minutes) but here’s how I store an array of dictionaries within an array of dictionaries:

  dim entityDict as new Dictionary
  
  entityDict.Value ("InspectionTaskId") = InspectionGUID
  entityDict.Value ("InspectionReportId") = InspectionReportGUID
  
  dim areasDict() as Auto
  
  for each area as InspectionArea in Areas
    dim areaDict as new Dictionary
    areaDict.Value ("Id") = area.InspectionAreaGUID
    areaDict.Value ("Number") = area.Number
    areaDict.Value ("Name") = area.Name
    areaDict.Value ("Note") = area.Note
    areaDict.Value ("IsDeleted") = area.Deleted
    
    dim photosDict() as Auto
    
    for each doc as Document in area.Documents
      dim photoDict as new Dictionary
      photoDict.Value ("DocumentStorageId") = doc.DocumentGUID
      photoDict.Value ("Note") = doc.Notes
      photoDict.Value ("IsDeleted") = doc.Deleted
      photosDict.Append photoDict
    next
    
    areaDict.Value ("Photos") = photosDict()
    
    areasDict.Append areaDict
  next

  entityDict.Value ("ReportAreas") = areasDict
  
  'Convert the dictionary
  dim requestContent as text = GenerateJSON(entityDict)
 
  //Next POST the request...

Edit: I only do one GenerateJSON after all the arrays of dictionaries have been created.

Ok, thanks for that. I got it to work by eliminating the second Generate/Parse JSON and by assigning json.Value(“team”) to an array of Auto and looping through that array, assigning the auto to a temporary dictionary. I guess the problem for me was thinking that the handling of the JSON and reconstruction of objects by ParseJSON was not returning objects in the same form as I passed into GenerateJSON, but instead using an array of Auto instead of dictionary. This is probably expected behavior, but it does mean that code which turns an array of dictionaries into JSON cannot work in the exact opposite direction of how the dictionaries were created originally.

What would be nice is a way to serialize a class into and out of JSON. I work with a bunch of C# guys (they do the web services) and this is all just handled for them.