Arcade - Validation of JSON data in string field?

1564
7
08-08-2023 12:41 PM
Labels (3)
davedoesgis
Frequent Contributor

I have a feature service that has a string field containing JSON values. I can easily convert those into Arcade Dictionary objects in my popups. If a record hasn't been populated, it is null, and I can easily test for that, or it will just create an empty Dictionary. For example:

 

// Valid JSON passed in as serialized string
var testFieldValue = `{"Bart":"Simpson","foo":["a","b"]}`
var testDict = Dictionary(testFieldValue)
Console(`TypeOf: ${TypeOf(testDict)}; value: ${testDict}`)
// OUTPUT: TypeOf: Dictionary; value: {"Bart":"Simpson","foo":["a","b"]}

// Null value
testFieldValue = null
testDict = Dictionary(testFieldValue)
Console(`TypeOf: ${TypeOf(testDict)}; value: ${testDict}`)
// OUTPUT: TypeOf: Dictionary; value: {}

 

 

Because the field is a string field, it should always contain a string or a null, but what if the string isn't valid JSON? Even just an empty string blows this up:

 

// Garbage data - how do I test for this? Try/catch? 
testFieldValue = ""
testDict = Dictionary(testFieldValue)
Console(`TypeOf: ${TypeOf(testDict)}; value: ${testDict}`)

 

That raises this error in my console. If I expand the drop-downs, there are lots of lines of stack trace, but nothing I can act on.

dcafdg_0-1691522269550.png

This is a trivial example, but imagine the field contains improperly formatted JSON data (e.g.: missing a closing quote or bracket). I'd get the same result.

Is there a way to validate the text in a field before running it through the Dictionary() function? How about some way to handle the error, like a try/catch statement? The code above crashes my popup and nothing displays, so it's real deal-breaker if my Feature Service has bad data.

0 Kudos
7 Replies
RichardHolowczak
Emerging Contributor
0 Kudos
RichardHolowczak
Emerging Contributor
0 Kudos
davedoesgis
Frequent Contributor

Yes, if it is just an empty string, I can test for that and handle it. My bigger concern is something like a JSON object that has a small error in it, like this, which is missing a closing square bracket on the array. 

testFieldValue = `{"a": "this is a long, invalid json object", 
                   "b": ["no", "closing", "bracket"}`
testDict = Dictionary(testFieldValue)
Console(`TypeOf: ${TypeOf(testDict)}; value: ${testDict}`)

 

I could also see garbage non-JSON strings creeping into the data at some point.

 

How do I test for these cases and/or catch the error before it crashes my popup?

 

0 Kudos
RichardHolowczak
Emerging Contributor

Probably overly cumbersome but one idea is to count the number of left square brackets and then count the number of right square brackets and see if you get the same counts.

Maybe a loop using the FIND function to step through the testFieldValue string. Something like this (I did not test this but hopefully you can get an idea).

function count_chars(mychar, mystring)
{
   var mycount = 0;
  var start = 0;
  var length = COUNT(mystring);
  start = FIND(mychar, mystring, start+1);
   while(start < length && start != -1)
   {
      mycount++;
      start = FIND(mychar, mystring, start+1);
  }
return mycount;
}

davedoesgis
Frequent Contributor

Ha, I thought about this, too! There's just so many ways this could go sideways. It seems simple enough on the surface,  but feels like a task bound to snowball in complexity. As far as I can tell, there's no way to write a reusable library, so it seems like a lot to add JSON validation just to produce a popup.

Note that I also tried the FromJSON() function. I was hoping that serialized JSON with errors would just result in a String variable, but this also produced an error similar to the Dictionary() function.

0 Kudos
RichardHolowczak
Emerging Contributor

For sure there are lots of ways an input doc. can be mis-formatted. There were posts going back 5 or 6 years asking for a try..catch.   Hopefully something like that will be available soon.

0 Kudos
KenBuja
MVP Esteemed Contributor

There's no try/catch available right now, but those are in the future keywords list of reserved words, so hopefully that will be implemented in a coming release.