Question
· Apr 17

MAXSTRING %ToJSON()

I have see this discussed on the community but I'm not quite finding an answer. 

I have a method that is called in the OnPreHttp() method of a CSP page.  That method returns a dynamic object and a set a new variable to the %ToJSON method of the object so I can use it in my JavaScript code later to init a table of data (using the #(variable)# syntax).  This creates a MAXSTRING error.  So I changed it to return a %Stream.TmpCharacter.  But if I call Read($$$MaxStringLenght) I only get part of the data.  I loop over it and read it in chunks to the end, that kind of work, but I can't set the chunks to a variable because then I'll run into MAXSTRING.  I can't use Javascript to iterate over it because Javascript and COS don't mix like that.

I can't be the first person ever to have JSON data that big.  What have people come up with?

The only alternate solution I've come to think of is to write the data to a temp file on the server and then read the data from the file using a Javascript fetch or something like that.

Product version: IRIS 2025.1
Discussion (3)3
Log in or sign up to continue

Not enought detail here to see exactly what you are encountering but %LIbrary.DynamicObject in the %Set method supports

 method %Set(key, value, type) as %DynamicAbstractObject

Create a new value or update an existing value.

key The key name of the value you wish to create or update.

value The new value with which to update the previous value or create a new value.

type OPTIONAL, the 'type' of the value being assigned.

If the 'type' argument is present then its value must be one of the following string values: ""          - %Set(key,value) without conversions
"null"        - "" becomes null; else assign with no conversion
"boolean"      - 0/nonzero becomes JSON false/true
"number"      - Convert to numeric value
"string"       - Convert to text string
"string>base64"  - Convert to text string then encode into base64
"string<base64"  - Convert to text string then decode from base64
"stream"      - %Stream contents converted to text string
"stream>base64" - %Stream contents are encoded into base64 string
"stream<base64" - %Stream is decoded from base64 into byte string

 so if one if your fields is greater than the max string lenght usage of type properly would place the data in a stream object. 

Another alternative is to not use %LIbrary.DynamicObject but rather define classes and extend from %JSON.Adaptor and define your properties with the correct data type, again for the field larger than Max. String Length as %Stream.GlobalCharacter.

While %Library.DynamicObject is quick and (not dirty) I prefer the approach of using %JSON.Adaptor except for the cases where the payload can change for some reason or another or over time.  The approach of defining your classes is purposeful as it defines the schema concretely(whether you think this is good or bad is up to you).

Hi @Stephen Canzano and thank you for the reply!

I essentially tried a similar approach doing this

set stream = ##class(%Stream.TmpCharacter).%New()

do myDynamicObject.%ToJSON(stream)

Where now the whole dynamic object is set to stream.  The problem comes when I send that stream back to the client.  I need the data in that stream for a JavaScript function so I read from the stream into a variable on the server.  However because it's so big, reading the stream into a variable to use in the JavaScript is causing the MAXSTRING error as well.

I tried wrapping it in a REST API but under the hood in the %Rest.Impl class the %WriteResponse is just calling a %ToJSON on the dynamic object which is causing the error.  It doesn't seem to be handling streams or if it does, it still wants to get my dynamic object into a JSON string but it's just too big.

The data does change over time, so I don't think the JSON adaptor is the right approach.

Thanks for any additional advice!