JSONItem.Child gives OutOfBoundsException

Can anybody reproduce this OR … what am I doing wrong ?

dim j as new JSONItem
  
  j.value("AAA") = "Alpha"
  j.value("BBB") = "Bravo"
  j.value("CCC") = "Charlie"
   
  dim jc as JSONItem
  dim i as integer
  
  for i = 0 to j.count-1           // 0 to 2
    jc = j.child(i)                       // OutOfBoundsException !!
    msgbox jj.ToString
  next

read the message of the exception?

It’s Error number 0 with no message …

jc is a JSONItem

j(0) - j(2) Are children of jc

They are not JSONItems but values of jc (similar to a dictionary)

Tough to wrap your head around at times.

Try this:

[code] dim j as new JSONItem

j.value(“AAA”) = “Alpha”
j.value(“BBB”) = “Bravo”
j.value(“CCC”) = “Charlie”

dim jc as JSONItem
dim i as integer

Dim myValues() As String = j.Names

for i = 0 to myValues.Ubound // 0 to 2jc.Append = j.child(i) // OutOfBoundsException !!

MsgBox myValues(i) + " value is " +  j.Value(myValues(i)).StringValue

next[/code]

You either store your “values” for each JSONItem as children (dictionary) or as arrays

You then look them up using either the dictionary methodology (hasName, lookup, etc) or the array methodology (append, insert, etc)

The Language reference on JSON.Child is confusing. There are four versions. Two apply to array children and two to dictionary children

These apply to Array Children
JSONItem.Child ( Index As Integer ) As JSONItem
Returns a child with the passed index. Index is zero-based. < - ONLY if it is an array child

MethodJSONItem.Child ( Index As Integer, Assigns obj As JSONItem )
Sets a child to a JSONItem by index. Index is zero-based.

These apply to Dictionary Children
MethodJSONItem.Child ( Name As String ) As JSONItem
Returns a child with the passed name.

MethodJSONItem.Child ( Name As String, Assigns obj As JSONItem )
Sets a named child to a JSONItem.

I also checked this and the Name function gives name by index. Than pick value by name.

I tried to remove the top half of my post as it was rambling. Christian’s post locked me out :stuck_out_tongue:

The bottom half hopefully gets you squared.

The OutOfBounds is misleading because count returns an accurate count.

Drove me nuts when I first started using it.

Well while the functionality seems illogical (and the help files lacking) your explanation sounds very positive. Let me test this and report back for all …

Peter and Christian,

Many thanks for your assistance.

Cheers … Ian

Of course it’s not logical, but well, it works and they can’t really change it, I think, without breaking code.

It’s important to remember that JSONItems are not just wrapped dictionaries. The keys are case-sensitive, and the values are limited as to what they can contain. Specifically: Strings, Numbers, Booleans, Nil and other JSONItems.

Our JSONItem class (for better or for worse) was modeled after the folderitem class, but the main reason for the Child method vs the Value method is so autocomplete works. Use Child for everything where you don’t want to have to cast to a JSONItem. When you get to the end points, where you’re actually retrieving values, use the Value method. That way you can use the BooleanValue, StringValue, etc… Methods to get the exact type that you need.

Greg,

This explanation is valuable. Can you expand a little or pen a short example. Just not clear on the meaning of “autocomplete” or “casting” in this context.

Thanks … Ian

Sure. For example, given a json string like this:

{ "person":{ "name":"Frank", "age":32, "married":true } }

Put this code in the code editor

dim js as string = "{""person"":{""name"":""Frank"",""age"":32,""married"":true}}"
dim p as new jsonitem(js)

on the next line, type: p. you’ll find that autocomplete shows you all of the methods that are available to a jsonitem.

If you type further: p.child("person").Value("name"). you’ll find that because Value returns a Variant, you can specify the type now… so you could finish this line as p.child("person").Value("name").StringValue (or BooleanValue, or IntegerValue, or DoubleValue, etc…)

AutoComplete is all about having the code editor help you figure out the commands that are available based on what’s in context. Casting has to do with the fact that because JSON values can be one of several types, we used a Variant. This means that autocomplete can’t tell, and neither can your code in some cases. By specifying the type explicitly, you can fix those bugs sometimes. Check out the Properties of the Variant class: http://documentation.xojo.com/index.php/Variant