Retrieving Dictionary value within a Dictionary

I am working with results from an API interface and am trying to retrieve the “id” value from a jSON string.

I have the following code:

dim js as New JSONItem(s) dim dict as New Xojo.Core.Dictionary dict = xojo.Data.ParseJSON(s.ToText)

which now gives me a dictionary of 3 items (previous, next, results).

The value I want is in the results which is type “Auto” so I am guessing it is an array.

When I run the following code:

Dim myAutoArray() As Auto = dict.Value("results")

I get an array of Xojo.Core.Dictionary

I am confused on how to get the “id” value from the dictionary?

No need to guess. You can tell by looking at the JSON. Perhaps post a sample of the JSON here? Otherwise it’s hard to offer a suggestion.

Here is a sample of the JSON:

{“previous”:null,“results”:[{“id”:72671236,“chart_id”:“BRCH000001”,“first_name”:“Chrissy”,“middle_name”:null,“last_name”:“Bright”,“nick_name”:"",“date_of_birth”:“1971-09-10”,“gender”:“Female”,“social_security_number”:“111-11-1111”,“race”:“blank”,“ethnicity”:“blank”,“preferred_language”:“blank”,“patient_photo”:“https://f1909d387b0a88bc2ca9-bd47d22792a78846d62f19961d548210.ssl.cf5.rackcdn.com/patient_photos/3bd6f9a1-a88c-4008-9229-ff581f4ff871.jpg",“patient_photo_date”:null,“patient_payment_profile”:“Cash”,“patient_status”:“A”,“home_phone”:"",“cell_phone”:"",“office_phone”:"",“email”:"",“address”:"",“city”:"Mountain View”,“state”:“CA”,“zip_code”:“94040”,“emergency_contact_name”:"",“emergency_contact_phone”:"",“emergency_contact_relation”:null,“employer”:"",“employer_address”:"",“employer_city”:"",“employer_state”:"",“employer_zip_code”:"",“disable_sms_messages”:false,“doctor”:209372,“primary_care_physician”:"",“date_of_first_appointment”:“2018-03-12”,“date_of_last_appointment”:“2018-04-04”,“offices”:[219444],“default_pharmacy”:"",“referring_source”:null,“copay”:"",“responsible_party_name”:null,“responsible_party_relation”:null,“responsible_party_phone”:null,“responsible_party_email”:null,“updated_at”:“2018-05-08T00:02:43”}],“next”:null}

dict = xojo.Data.ParseJSON(s.ToText)

dict = xojo.Data.ParseJSON(s.ToText)

or

dict = xojo.Data.ParseJSON(js.ToText)

You are defining js as a new JSON item but then do not seem to use it. (It is quit possible that I am confused but it made me wonder)

I was thinking that the JSON text would be easier to work with in a dictionary so I could look up the “id” value.
Didn’t realize there was an orphan JSON variable left hanging around. Thanks for pointing that out.

@David Schlam: A hint: Set JsonItem.Compact = False for better readability.
A great source to see the content of a JSONItem is http://jsonviewer.stack.hu. It gives you a tree view of any JSON pasted as text into it.

1 Like

Until someone more informed has time to answer, as a beginner (warning) I parse the JSON as:

The value of result is an array since it is delimited by [ ].

That array has only one element since there are no commas in the scope of [ ].

That one element is delimited by { }. Since it is delimited by { } that one element is a dictionary.

To access that one element: --> result(0) refers to that element, i.e. that dictionary

To access the “id” value

result(0).Value("id")

Should return 72671236

If this does not work, see the first line of this post :slight_smile:

results is an array of JSONItems, so you can walk the array and process each result if you like using .Count and .Value(index as integer).

[code]dim js as New JSONItem(json)

dim results as JSONItem=js.Value(“results”)

if results.IsArray then

for i as integer=0 to results.Count-1
dim nextresult as JSONItem=results.Value(i)
dim ID as integer=nextresult.value(“id”)
Break
next

end if[/code]

I did not realize that you could pull a value from a JSONItem the same way you could pull one from a dictionary. I thought you had to convert the JSON into a dictionary first.

I couldn’t do this command:

result(0).Value("id")

because the result is an array.

What’s interesting is that in this code:

[code]if results.IsArray then

for i as integer=0 to results.Count-1
dim nextresult as JSONItem=results.Value(i)
dim ID as integer=nextresult.value(“id”)
Break
next

end if[/code]

nextresult loads the entire JSON array on the first pass. Not sure why you need to put it in a loop.

Edit: I think I just realized why. Suppose the result pulls more than one record, then there would be more than one result.

FYI, where the JSON represents an array, you can use this shortcut.

dim item as variant = results( i ) // instead of results.Value( i )

Kem,

Why not use:

dim item as JSONItem = results( i )

I was providing a generalized example that would work with any type of element. In this case, you should.

Thank you all. I have a much better understanding of JSON now.

This is a bit of code (verbose for the sake of clarity) that grabs the “id” value. In my testing (just putting this code into a button) it works with the JSON that was supplied by the original poster.

Step 1: Create a text file that contains the JSON supplied by the original poster.
{“previous”:null,“results”:[{“id”:72671236,“chart_id”:“BRCH000001” … etc.

Step 2: Run the code provided below:
You open the text file that was created in Step 1.
The code will place that text in the string theJSON_String
The code will parse out the “id” that was desired.

[code]// The following code gets the JSON string sitting in a file placed inside of theJSON_String variable
// This is basically copied from the XOJO documention of TextInputStream
Dim f As FolderItem = GetOpenFolderItem(“text”) // as defined in File Type Sets Editor
Dim theJSON_String As String
If f <> Nil Then
If f.Exists Then
// Be aware that TextInputStream.Open could raise an exception
Dim t As TextInputStream
Try
t = TextInputStream.Open(f)
t.Encoding = Encodings.UTF8
theJSON_String = t.ReadAll
Catch e As IOException
MsgBox(“Error accessing file.”)
End Try
t.Close
End If
End If

// The following code takes the theJSON_String and parses it
// And retrieves the “id” contents
Dim origDict As New Xojo.Core.Dictionary
origDict = Xojo.Data.ParseJSON(theJSON_String.ToText)

Dim resultsArray( ) As Auto
resultsArray( ) = origDict.Value(“results”)

Dim resultDict As New Xojo.Core.Dictionary
resultDict = resultsArray(0)

Dim contentID_Variant As Variant
contentID_Variant = resultDict.Value(“id”)

Dim contentID_String As String
contentID_String = contentID_Variant

MsgBox(contentID_String) // 72671236
[/code]