NetTalk Central

Author Topic: Jfiles - List arrays  (Read 8050 times)

willie53

  • Newbie
  • *
  • Posts: 25
    • View Profile
    • Email
Jfiles - List arrays
« on: June 11, 2015, 08:06:31 AM »
I've been trying to read the structure below, and having a hell of a time with it.
I'm able to get the record count (4), and the labels for the fields.

but I'm unable to get  the values for destination_addresses and origin_addresses .
 
I've set up the field to be a queue with an external name of origin_addresses on the first field, but nothing I've tried works.
Does jfiles support working with  list arrarys? is there a specific way I must set up my receiving structure?

    public List<string> destination_addresses { get; set; }
    public List<string> origin_addresses { get; set; }


!!----------------------------------------------------------Json File

{
   "destination_addresses" : [ "5010 Cattleridge Drive, Sarasota, FL 34232, USA" ],
   "origin_addresses" : [ "6615 Anchor Loop, Bradenton, FL 34212, USA" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "16.5 mi",
                  "value" : 26580
               },
               "duration" : {
                  "text" : "20 mins",
                  "value" : 1198
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}

willie53

  • Newbie
  • *
  • Posts: 25
    • View Profile
    • Email
Re: Jfiles - List arrays
« Reply #1 on: June 23, 2015, 08:54:24 AM »
This is a another JSon response it's having a hard time with.. again this response is from googlemaps.
It can't read the array or locate it.

{
   "destination_addresses" : [
      6000 Cattleridge Drive, Sarasota, FL 34232, USA",
      "3937 Westminster Drive, Sarasota, FL 34241, USA"
   ],
   "origin_addresses" : [
      "6615 Anchor Loop, Bradenton, FL 34212, USA",
      "121 New Briton Court, Bradenton, FL 34212, USA"
   ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "16.5 mi",
                  "value" : 26580
               },
               "duration" : {
                  "text" : "20 mins",
                  "value" : 1198
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "17.0 mi",
                  "value" : 27391
               },
               "duration" : {
                  "text" : "21 mins",
                  "value" : 1255
               },
               "status" : "OK"
            }
         ]
      },
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "16.8 mi",
                  "value" : 27110
               },
               "duration" : {
                  "text" : "21 mins",
                  "value" : 1234
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "17.3 mi",
                  "value" : 27922
               },
               "duration" : {
                  "text" : "22 mins",
                  "value" : 1291
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}

Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: Jfiles - List arrays
« Reply #2 on: June 24, 2015, 01:59:37 AM »
Hi Willie,

Sorry for the long wait - I've spent quite a bit of time on this only to realize that a bug in my _debugging_ output caused me to be looking in completely the wrong place. Turns out jFiles is working just fine, such is the programming life sometimes.

I have added some convenience methods though during this process - so you will need build 1.08 or later to follow these instructions.

So, to answer your question - there are a couple ways to get at the data. First the "manual" way;
I'm assuming you're starting with a string or StringTheory object (but you could just as easily start with a file.)

json  JsonClass
st     string(255)

  json.LoadString(responseString)
  ! at this point the json is loaded, but only as far as the json object.

  st = json.GetValueByName('destination_addresses',1) ! first address
  st = json.GetValueByName('destination_addresses',2) ! second address

So it's easy enough to get at specific values, or even specific array values.

You could also create a group to put this into. (it's an Array in the json, so it best fits an array in clarion.)

WGroup                 GROUP,pre()
destination_addresses    string(255),dim(10)
                       end
json               JsonClass

  json.start()
  json.TagCase = jF:CaseLower
  json.load(wGroup,responseString)
  ! now the addresses are in WGroup.destination_addresses[1] and WGroup.destination_addresses[2]


I think this deals with the second one as well. Let me get the build up, then you can try it and let me know.

cheers
Bruce

-- update : jFiles 1.08 is up.



« Last Edit: June 24, 2015, 05:55:59 AM by Bruce »

willie53

  • Newbie
  • *
  • Posts: 25
    • View Profile
    • Email
Re: Jfiles - List arrays
« Reply #3 on: June 26, 2015, 06:45:46 AM »
Hi Bruce,
I know you're busy person, I just don't know how you do it with so many products and supporting other vendors.

I was able to get to get the address information working but no matter what I do I'm not able to get the element | Distance information

When I try to get the 1st element using the information is correct, but for the 2nd it gets the value" : 26580  instead of  text" : "17.0 mi",
Also I can't seem to be able to reach the 2nd element either.

MatrixElements  GROUP,PRE(ED)
Distance          CSTRING(145),DIM(50),NAME('text')
                END


    json.start()
    json.Loadstring( str )
    x = json.Records()

        ED:Distance[1] = json.GetValueByName('distance',1) ! first address 
        ED:Distance[2] = json.GetValueByName('distance',2) ! first address

The Json Response file:

{
   "destination_addresses" : [
      "6010 Cattleridge Drive, Sarasota, FL 34232, USA",
      "3937 Westminster Drive, Sarasota, FL 34241, USA"
   ],
   "origin_addresses" : [
      "6615 Anchor Loop, Bradenton, FL 34212, USA",
      "121 New Briton Court, Bradenton, FL 34212, USA"
   ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "16.5 mi",
                  "value" : 26580
               },
               "duration" : {
                  "text" : "20 mins",
                  "value" : 1202
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "17.0 mi",
                  "value" : 27391
               },
               "duration" : {
                  "text" : "21 mins",
                  "value" : 1254
               },
               "status" : "OK"
            }
         ]
      },
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "16.8 mi",
                  "value" : 27110
               },
               "duration" : {
                  "text" : "21 mins",
                  "value" : 1243
               },
               "status" : "OK"
            },
            {
               "distance" : {
                  "text" : "17.3 mi",
                  "value" : 27922
               },
               "duration" : {
                  "text" : "22 mins",
                  "value" : 1295
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}

JPMacDonald

  • Full Member
  • ***
  • Posts: 106
    • View Profile
    • Email
Re: Jfiles - List arrays
« Reply #4 on: June 28, 2015, 11:23:25 AM »
Hi Willie,

I have a vested interest in a solution to your problem so I've been taking a crack at it, alas with no success :'(

I thought this would work (but it doesn't) I loaded your response into a file for processing:

jObject             JSONClass
jsonItem            &JSONClass


elementsQ           QUEUE
distance                GROUP
text                        STRING(50),name('text')
value                       STRING(50),name('value')
                        END
duration                GROUP
text                        string(50),name('text')
value                       STRING(50),name('value')
                        END
status              STRING(50),name('status')
                    END

jObject.Start()
IF jObject.LoadFile('C:\bin\jsonResponse.json') = jf:Error
    MESSAGE('json LoadFile Failed: ' & jObject.Error)
END

jsonItem &= jObject.GetByName('elements')
If not jsonItem &= Null
    jsonItem.Load(elementsQ)
ELSE
    message('Failed to get "elements" object')
End
message('Qrecords = ' & Records(elementsQ))

LOOP X# = 1 to Records(elementsQ)
    GET(elementsQ,X#)
    myText = Clip(myText) & '<13,10>' & elementsQ.distance.text
END
Display()

The Queue is always empty dang it!

If you were processing this response in javascript you would access the elements something like this:

alert(jsonResponse.rows[0].elements[0].distance.text);
alert(jsonResponse.rows[0].elements[1].distance.text);
alert(jsonResponse.rows[1].elements[1].distance.text);

Wouldn't it be sweet if we could do that in jFiles:

jObject.GetValueByName('rows[1].elements[1].distance.text,1')

I understand this is of no help to you but you are not alone trying to understand this.

Looking forward to seeing Bruce's approach to this.

Regards

Parker

willie53

  • Newbie
  • *
  • Posts: 25
    • View Profile
    • Email
Re: Jfiles - List arrays
« Reply #5 on: June 29, 2015, 01:03:42 PM »
Hi there,
That's exactly the problem I have!
The queue always comes up empty, I've many different layouts and none as of this moment works.
it seems that googlemaps uses an unconventional way of formatting the responses.  I too am anxious to see how Bruce would approach this.

I have classes for the file structures and write the responses to a SQL table and return a pointer to the record when called from my rest service, but that takes jfiles out of the picture and I don't want to do that as this time.

Thanks for your interest in this.


Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: Jfiles - List arrays
« Reply #6 on: June 30, 2015, 12:34:46 AM »
Hi Parker,

You were pretty close mate - here's what I ended up with;

json                 Class(JSONClass)
                     End
elements             &JsonClass   
rows                 &JSONClass
onerow               &JsonClass

elementsQ           QUEUE
distance                GROUP
text                        STRING(50),name('text')
value                       STRING(50),name('value')
                        END
duration                GROUP
text                        string(50),name('text')
value                       STRING(50),name('value')
                        END
status              STRING(50),name('status')
                    END

  code
    json.start()   
    json.TagCase = jF:CaseLower
    json.loadFile('d.json')   
    rows &= json.GetByName('rows')
    loop x = 1 to rows.records()
      onerow &= rows.Get(x)
      elements &= onerow.GetByName('elements')
      elements.load(ElementsQ)
    end


You got really close because you summed it up as;

>> If you were processing this response in javascript you would access the elements something like this:
>> alert(json.rows[0].elements[0].distance.text);

In JavaScript you can have an "array of objects" (hence the [n]) whereas in clarion we "loop through" for want of a better expression.  So the above in Clarion translated to

    rows &= json.GetByName('rows')
    loop x = 1 to rows.records()
      onerow &= rows.Get(x)
      elements &= onerow.GetByName('elements')
      elements.load(ElementsQ)
    end


This is certainly longer, but I'm not sure it's "worse".

>> Wouldn't it be sweet if we could do that in jFiles:
jObject.GetValueByName('rows[1].elements[1].distance.text,1')

It's an intriguing idea, and possibly do'able - I'm not going to discount it yet - but I think it would be a fair bit slower than the code above because it would be "interpreted" whereas my code is "compiled".

Aside: In debugging this I did make a couple tweaks to the code, they shouldn't affect the working, but it's a little bit faster, and so I'll make a new build anyway. That will be build 1.09.

Cheers
Bruce



JPMacDonald

  • Full Member
  • ***
  • Posts: 106
    • View Profile
    • Email
Re: Jfiles - List arrays
« Reply #7 on: June 30, 2015, 03:52:56 AM »
Thanks Bruce, there is some good study material in this response.
I'll be printing that out and tucking it in "the binder" for future reference as well.

It would be nice if the proposed access to the json object array

  jObject.GetValueByName('rows[ x ].elements[ y ].distance.text')

wasn't so slow as to make it impractical, and of course the effort on your part to code it too unreasonable.

Thanks again,

Parker
« Last Edit: June 30, 2015, 03:58:14 AM by JPMacDonald »

JPMacDonald

  • Full Member
  • ***
  • Posts: 106
    • View Profile
    • Email
Re: Jfiles - List arrays
« Reply #8 on: June 30, 2015, 06:12:11 PM »
Hi Bruce,

I think there is still a piece of this puzzle missing.
When I try this code I only get the last 2 element entries, there are only 2 entries in the queue and I would have expected 4.
I added another set of element entries to Willie's json data and again I only get the last 2.

Is it possible that the elements.Load(elementsQ) is clearing the queue on each iteration instead of appending?

Regards

Parker

Bruce

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 11250
    • View Profile
Re: Jfiles - List arrays
« Reply #9 on: June 30, 2015, 11:10:29 PM »
Hi Parker,

>> Is it possible that the elements.Load(elementsQ) is clearing the queue on each iteration instead of appending?

Absolutely it is. If you want it to Append to the queue then set

json.FreeQueueBeforeLoad = false

Whether you do or not depends on how you plan to process the Elements. I'm thinking that the Elements themselves are tied to a Row - so maybe you'll need to add some sort of a RowID to the elementsQ?

cheers
Bruce


willie53

  • Newbie
  • *
  • Posts: 25
    • View Profile
    • Email
Re: Jfiles - List arrays
« Reply #10 on: July 31, 2015, 07:44:45 AM »
I think it gets a bit more complicated to read this json script since the origin and destination addresses also need to be accounted for.

json                 Class(JSONClass)
                     End
addresses             &JsonClass   
elements             &JsonClass   
rows                 &JSONClass
onerow               &JsonClass

elementsQ           QUEUE
addresses               GROUP
OriAddresses           STRING(50),name('origin_addresses')
DesAddresses           STRING(50),name('destination_addresses')
                        END

distance                GROUP
text                        STRING(50),name('text')
value                       STRING(50),name('value')
                        END
duration                GROUP
text                        string(50),name('text')
value                       STRING(50),name('value')
                        END
status              STRING(50),name('status')
                    END
code
    json.start()   
    json.TagCase = jF:CaseLower
    json.loadFile('d.json')   

???

    rows &= json.GetByName('rows')
    loop x = 1 to rows.records()
      onerow &= rows.Get(x)
      elements &= onerow.GetByName('elements')
      elements.load(ElementsQ)
    end