JSONItem not instantiating empty arrays correctly

I’m running into a problem with the way that JSONItem instantiates empty arrays.

  Dim obj As new JSONItem("[]")
  
  if obj.IsArray then
    MsgBox "JSON arrays are awesome."
  else
    MsgBox "I'm not an object, I'm an array?" // this should not display
  end if

In the above code, the obj.IsArray value is false. Obj.ToString() also returns “{}”, instead of “[]”, which is different than the string that obj was initialized with.

Is anyone else also seeing this issue?

Bump

Yes it’s a bug
But is not only on instantiating

dim obj as new jsonItem("[1]")
msgbox obj.toString // ->[1] OK

obj.remove(0)
msgbox obj.toString //->{} BAD expected []

Thanks for confirming Antonio.

I’ll open a feedback case for this.

It might seem like a trivial issue, but I use JSON extensively in communication protocols, and sometimes need to indicate that a certain value is an array by giving it a value of “[]” (initializing the value as [“1”] or something similar is not an option).

Have you thought about using Count instead of IsArray? Count will return zero for {}.

I doubt that Count will solve my problem…

  Dim item1 As New JSONItem("[]")
  Dim item2 As New JSONItem("{}")

Both item1.Count() and item2.Count() is equal to 0.

My JSON objects are serialized on the one side to a string with the ToString() method, and deserialzed on the other side with the JSONItem constructor… and because ToString() changes empty arrays (e.g. []) to objects ({}) the data “type” comes out wrong at the other side.

The bug is basically that…

Dim item1 As New JSONItem("[]")

is not setting

item1.IsArray = True

as it should.

[code] Dim obj As new JSONItem("[""""]")

if obj.IsArray then
MsgBox “JSON arrays are awesome.”
else
MsgBox “I’m not an object, I’m an array?” // this should not display
end if[/code]

I added the empty string in the array and the array message box got triggered…

I’ve tried the “adding one element” workaround, but for technical reasons beyond the scope of this post, I need that an “empty” arrays are correctly instantiated.

Just a brief explanation through code why.

Dim obj1 As new JSONItem("[""""]")
Dim obj2 As new JSONItem("{}")
Dim obj3 As new JSONItem("[]")

// obj1 is an array and obj1.Count = 1 : CORRECT
// obj2 is an object and obj2.count = 0 : CORRECT
// obj3 is an object : INCORRECT

For my program, I need to create a JSONItem that is an array and constains zero elements… and I cannot find a way of doing this.

I see this issue is already logged in feedback.

<https://xojo.com/issue/25725>

[quote=68323:@Alwyn Bester]The bug is basically that…

Dim item1 As New JSONItem("[]")

is not setting

item1.IsArray = True

as it should.[/quote]
IsArray is not a property… It’s a method which simply checks to see if Count > 0.

FWIW, I’m not defending our implementation, just telling you why it behaves this way.

Thanks Greg, and I appreciate the feedback.

I’ve added my support in feedback, but luckily also found a workaround for this in the meantime… so it isn’t a showstopper anymore. :wink:

BTW, shouldn’t you be sleeping Greg? It is 2:14AM in Florida?

Which Count are you referring?

There is only one Count method on a JSONItem.

Wish I could. I have insomnia occasionally, and since I hate to be idle! I come here and answer questions.

Man I hate typing on an ipad. I can’t un-answer the thread…

Yes I know,
Maybe you should not take the count method to check if it’s an array or not.
If you parse a “[…]” structure then it’s an array
If you assign a indexed value (i.e. jsonItem.append) then it’s an array
if you remove an indexed item (i.e. jsonitem.remove) you should not reflag the array type (documentation asserts that once you assign a type for an item then it’s of that type)
Now count is useful for its real meaning : the item has count info in it; not it’s an array or not.

+1

Perhaps I’m getting old, and the cool kids growing up with tablets are more comfortable with touch typing, but I much rather prefer a good old 101 keyboard.

I am more than willing to make my workaround class for this issue available to anyone else that needs it.

While working on a MongoDB driver for Xojo I wrote a JSON parser capable of parsing less strict JSON (e.g. {mykey:“myvalue”} instead of {“mykey”:“myvalue”}), so it was a quick exercise for me to wrap this existing code as a drop-in replacement class, with one difference… the IsArray is a property instead of a method.

This JSON parser is also used in my 3D engine to parse very large JSON strings very quickly.

Haven’t done any official testing about the correctness of the class, so I provide it “as-is” to those who might need it… so please use it at your own risk.

Can be downloaded from here.

Whoa, wAit a sec. Making a class that allows you to parse errors in a JSON string just encourages people to make bad JSON generators which won’t work anywhere else.

FWIW what you are talking about there is a JavaScript object (keys without quotes).