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
**********************************************************************

Reply via email to