I know this is not a new topic. I have read the past posts, but still cannot get this to work, even using the examples provided.
I am storing an array (of strings) in a dictionary, then exporting the dictionary to JSON using GenerateJSON. Inspecting the JSON file shows the array of strings propertly formatted.
Then I read file back into a TextInputStream and call ParseJSON (Xojo 2019 r3.1 Mac).
So far, so good, no Exceptions
Here is what happens when I try to access the result of ParseJSON
var x as integer
var s as string
var d as dictionary
var list() as string
var restoredData() as variant = ParseJSON( textFromInputStream )
for each dict as Dictionary in restoredData 'OK
x = dict.value("keyFor_AnInteger") 'OK
s = dict.value("keyFor_AString") 'OK
d = dict.value("keyFor_ADictionary") 'OK
list = dict.value("keyFor_StringArray") 'TYPE MISMATCH EXCEPTION
next
Ok, everything is a variant. I see that in the Docs
But the for…each loop iterator coerces a variant() into a dictionary() behind the scenes.
Not so for the string() stored in the dictionary.
I can view the data on disk, retrieve it, but not reference it. I cannot caste the variant back into a string(), nor loop it.
I have tried:
for each s as string in dict.value("keyFor_StringArray")
'Compiler says: This is not an array but you are using it as one
next
var retrieved() as string = data.value("keyFor_StringArray") 'Compiles, but
for each s as string in retrieved 'TYPE MISMATCH EXCEPTION
...
next
list = Array(dict.value("keyFor_StringArray")) 'NOPE..compiler says TypeMismatchError
var v as variant = dict.value("keyFor_StringArray")
if v.isArray then
//still cannot refernce the variant as an array
end if
There is an obvious trick here, but somehow I can’t see the forest through the trees.
The new framework JSON stuff is too ambiguous for my taste. It’s worlds faster, but it’s significantly harder to develop with. Classic framework JSONItem was always JSONItem and easy to work with.
my use of “keyFor_StringArray” was illustrative in my posting. The actual code is using another key, which is a different string, but the results are the same no matter what key I choose for the string(). Thanks
var d as dictionary
for each v as variant in restoredData
d = Dictionary(v)
....
next
The coercion (Variant to Dictionary) is now explicit, but the result is the same. The string() stored under (any) key yields a Type Mismatch Exception if I try to loop the variant returned from that key.
There must be a way to coerce the variant into String(), or loop the array and get the strings back out somehow.
The returned value stored in “list” is definitely a variant. Also, when testing for .isArray, the result is true:
if list.isArray then 'OK..true
for each s as string in list 'TYPE MISMATCH EXCEPTION here
...
next
end if
What I can’t seem to do is coerce the variant back into a string(), or reference any of the array indices because it doesn’t loop in an interator. Compiler rejects the code with “not an array” compiler message if I try to use any interation.
list is a variant. To use it, you need to assign it to a string array
dim list as variant = dict.value("keyFor_StringArray")
dim stringarray() as string = list
for each s as string in stringarray
// do something with s
next
Yes, your method worked. Many thanks
I had to test it with some real data, and of course it makes perfect sense (now) that each array item needs to be caste back to string, rather than the array itself.
I haven’t tested Tim Hare’s idea yet, but this also makes sense