You're running into the fact that calling %Get on a dynamic object doesn't return an undefined when data at the index you specify doesn't exist.  Instead, it returns "".

Both the answers you have here are great if you need a generalized solution.  If all you're looking for is a simple work around in a non-general case, all you need to do is check if your %Get returned "",  and if so, kill the value before you pass it in:

ClassMethod passIncompleteJSON()
  set json = ["arg1 val", "arg2 val"]
  set arg1 = json.%Get(0)
  kill:(arg1="") arg1
  set arg2 = json.%Get(1)
  kill:(arg2="") arg2
  set arg3 = json.%Get(2)
  kill:(arg3="") arg3
  write ..threeArgs(.arg1, .arg2, .arg3)

ClassMethod threeArgs(a, b, c)
  set:($get(c)="") c = "default"
  return a_"."_b_"."_c

Just be sure to pass in the parameters by reference since you're going to be passing in undefined variables.

(This does remove the distinction between undefined and "" though; you wouldn't be able to intentionally pass "" with this solution)

That $x thing is awesome.  Can't see this solution being beat.

Thanks a lot.  This is almost definitely what I'm looking for.

I'm building classes which contain representations of REST resources.  For example, a full (likely for administrators) representation of the "person" resource might contain all fields, and all of them are writable.  A limited (maybe authenticated, but non admin) representation might contain most fields, and some like name and email are writable, but others like employment status are not.  A minimal (maybe for unauthenticated users) representation would contain only a few, read-only fields.

The property parameters would be things like the name for the property we use in the JSON, whether the field is writable, other flags regarding how to represent relationships or object properties, etc.

I think what I'm imagining is very similar to the %XML.PropertyParameters class used by %XML.Adaptor

(If you're probably wondering why I didn't include all this in my original post, I've been discussing it with Tim Leavitt and my ideas are a lot more formulated than they were 2 hours ago.  I suspect that an analogous architecture to what's used with XML will work well.)

Oh okay, I see.  JSON_ARRAYAGG takes whatever results it gets back, and puts them into a JSON array.  Since JSON_OBJECT returns a bunch of results that are json objects, using JSON_ARRAYAGG(JSON_OBJECT( says to take all those json objects, and put them into a json array.

As far as the non select part of the query, it looks like you can specify it with a new "select", or without.  I.e.:

SELECT JSON_ARRAYAGG(JSON_OBJECT('state':Home_State)) FROM (select state from Sample.Person WHERE Home_State %STARTSWITH 'A')

Thanks a lot for taking the time to explain.  It's very clear to me what is happening now.

Thanks a lot.  This worked.

I found the page about this function for anyone who sees this later:

Would you mind explaining how exactly this particular line is working?  Why do you have to use both JSON_ARRAYARG and JSON_OBJECT and what does that syntax mean?  It looks like it's essentially "selecting" the data from one result set into another as JSON, but I'm not sure how.  What does the JSON_OBJECT call do here, and what does the JSON_ARRAYAGG call do?

Ah, using base-href is a great idea, thanks.  A few questions about this:

Why did you rename the files to .csp?

Why are you using ahead of time compilation?

By using:

ng build --base-href = /webapp_name/index.html

I was able to access <cname>/webapp_name/index.html successfully; the index.html file could find the scripts like polyfills.js without me modifying those src arguments by hand.