Hi folks, Here's a native 4D solution. This is something I just roughed out so consider it a starting point for your own work.
I noticed, and take advantage of, a couple of interesting aspects of how 4D handles c-objects. 1) OB GET($obj;"some key"; Is text) will almost always return the correct value as a text string. I say "almost" because I couldn't find this documented as an official thing and I haven't tried it with stuff like pointers. And it doesn't return c-objects as stringified JSON. So - almost. But it does seem reliable for text, numbers, booleans, and nulls. What about dates? Dates are turned into strings in a c-obj (and JSON) so they are actually already text. Not to worry. What about blobs? Big long text fields. 2) OB GET ARRAY($obj;"some array";$aText_arrary) works with everything except actual object arrays. And nothing in native 4D works with arrays containing mixed type (like an array with some number, some text and some objects as elements, which is valid JSON) though it will parse such an array. This aspect of using text is in keeping with what I've noticed working with other platforms that use JSON heavily - they frequently make all the JSON values text. I see this with DocuSign, for instance. Huge JSONs and every value is wrapped in double quotes. Put me off at first but as I worked with it came to appreciate the strategy - virtually no confusion about data type. When I needed a number I knew I had to turn the string into a number and change it back when writing. Was actually quite simple. This is the first time I've used the 'Additional text' parameter on a hierarchical list. I use it for the 'value'. The docs say it's a string which suggests it could hold up to 255 chars. I decided to limit this to 100 for cosmetic reasons. Since a text key could have a lot more data than that I put the entire data value into another custom parameter I call 'c_data' as hat tip to XML. Again the docs are a little unclear about whether this is text or string. I'm thinking text and I'm also thinking I wouldn't use this approach if I know I've got big text blocks in this JSON. A real draw back to using the hList is I can't figure out how to make the 'Additional data' part enterable. The keys are enterable is you make the list enterable. Nonetheless it does what I wanted: take a c-obj and display it in a hierarchical list. ============================== // Json_to_hList // Written by: Kirk as Designer, Created: 10/29/17, 04:06:00 // ------------------ // Method: Json_to_hList (c-obj; ptr; ptr) // $1 is c-obj // $2 is ptr list var // $3 is ptr to itemRef longint // Purpose: tranfer the c-obj to an hList Err_check_methodParams (3;Count parameters;Current method name) C_OBJECT($obj;$1) C_POINTER($2;$3) C_LONGINT($i;$n;$j) C_TEXT($errMsg) $obj:=OB_new $obj:=$1 $list_ptr:=$2 $itemRef_ptr:=$3 $list:=New list // this list will get this c-object $list_ptr->:=$list ARRAY TEXT($aKeys;0) ARRAY LONGINT($aTypes;0) OB GET PROPERTY NAMES($obj;$aKeys;$aTypes) SORT ARRAY($aKeys;$aTypes;>) $n:=Size of array($aKeys) For ($i;1;$n) $itemRef_ptr->:=$itemRef_ptr->+1 $itemRef:=$itemRef_ptr-> // the itemRef for this item Case of : ($aTypes{$i}=Is object) $subList:=New list Json_to_hList (OB Get($obj;$aKeys{$i};Is object);->$subList;$itemRef_ptr) APPEND TO LIST($list;$aKeys{$i};$itemRef;$subList;False) SET LIST ITEM PARAMETER($list;$itemRef;"type";$aTypes{$i}) : ($aTypes{$i}=Object array) $arrList:=New list ARRAY OBJECT($aObjs;0) ARRAY TEXT($aText;0) OB GET ARRAY($obj;$aKeys{$i};$aText) // most accomodating OB GET ARRAY($obj;$aKeys{$i};$aObjs) For ($c;1;Size of array($aText)) $value:=$aText{$c} $thisKey:=$aKeys{$i}+"["+String($c)+"]" If ($value="[object Object]") // this is an object $subList:=New list Json_to_hList ($aObjs{$c};->$subList;$itemRef_ptr) APPEND TO LIST($arrList;$thisKey;$itemRef;$subList;False) SET LIST ITEM PARAMETER($arrList;$itemRef;"type";$aTypes{$i}) Else // use this If (Length($value)>100) // could be 255 $c_data:=$value $value:=Substring($value;1;100)+"..." Else $c_data:="" End if APPEND TO LIST($arrList;$thisKey;$itemRef) SET LIST ITEM PARAMETER($arrList;$itemRef;Additional text;$value) SET LIST ITEM PARAMETER($arrList;$itemRef;"cData";$c_data) SET LIST ITEM PARAMETER($arrList;$itemRef;"type";Is text) $itemRef_ptr->:=$itemRef_ptr->+1 $itemRef:=$itemRef_ptr-> // the itemRef for this item End if End for // -------------------------------------------------------- APPEND TO LIST($list;$aKeys{$i};$itemRef;$arrList;False) SET LIST ITEM PARAMETER($list;$itemRef;"type";$aTypes{$i}) Else $value:=OB Get($obj;$aKeys{$i};Is text) If (Length($value)>100) // could be 255 $c_data:=$value $value:=Substring($value;1;100)+"..." Else $c_data:="" End if APPEND TO LIST($list;$aKeys{$i};$itemRef) SET LIST ITEM PARAMETER($list;$itemRef;Additional text;$value) SET LIST ITEM PARAMETER($list;$itemRef;"cData";$c_data) SET LIST ITEM PARAMETER($list;$itemRef;"type";$aTypes{$i}) End case End for On Sun, Oct 29, 2017 at 10:38 AM, Kirk Brooks <lists.k...@gmail.com> wrote: > I thought I had such a method but it seems I don't. Before I re-invent > this particular wheel does anyone have this already and are willing to > share? > > Thanks > > -- > Kirk Brooks > San Francisco, CA > ======================= > > *The only thing necessary for the triumph of evil is for good men to do > nothing.* > > *- Edmund Burke* > > -- Kirk Brooks San Francisco, CA ======================= *The only thing necessary for the triumph of evil is for good men to do nothing.* *- Edmund Burke* ********************************************************************** 4D Internet Users Group (4D iNUG) FAQ: http://lists.4d.com/faqnug.html Archive: http://lists.4d.com/archives.html Options: http://lists.4d.com/mailman/options/4d_tech Unsub: mailto:4d_tech-unsubscr...@lists.4d.com **********************************************************************