Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 24 total
Thread How do I parse JSON from the server?
Mon, Apr 13 2015 6:26 PMPermanent Link

Doug B

I'm returning a custom JSON string and need to parse the elements from it.

Is there a way to return a dynamic object type like JavaScript allows you to do via JSON.Parse()?

Example:

http://www.w3schools.com/json/json_eval.asp

TParser seems far too complicated when a JavaScript object supports native parsing as per the above.

Ideally, I'd like to do something like the following example:

function GetCustomerName: string;
var
 Obj: TJSONObject;
begin
 Obj := JSON.Parse('{"ServerData": {"Customer": {"Name":"Bob"}}}');
 Result := ServerData.Customer.Name;
end;

Thanks,
Doug
Tue, Apr 14 2015 8:29 AMPermanent Link

D.C.

Hi Doug,
You could put something like this into an EWB external javascript file:

function GetCustomerName(json){
 var oJson = JSON.parse(json);
 return oJson.ServerData.Customer.Name; //I didn´t test it, the path may be different
}

Declare in EWB

external function GetCustomerName(json: string): string;

And call it:

CustName:=GetCustomerName('{"ServerData": {"Customer": {"Name":"Bob"}}}');

Regards
Diego
Tue, Apr 14 2015 2:31 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Doug,

<< TParser seems far too complicated when a JavaScript object supports
native parsing as per the above. >>

Yes, but how do you know that what you've parsed is what you *thought* you
were parsing ?   IOW, what happens if ServerData.Customer.Name isn't
actually defined because it didn't exist in the inbound JSON ?

EWB 2 will allow for saving/loading objects to/from JSON with a single call.
It still uses TParser, though, since using a parser allows for better
validation and simply avoids an additional step of having to iterate the
properties in the parsed objects and determine which properties exist, if
they're the correct type, etc.

Tim Young
Elevate Software
www.elevatesoft.com
Thu, Apr 16 2015 4:00 PMPermanent Link

Doug B

Thanks, Tim.

It's great to hear that serialization will be supported natively in EWB 2 with validation.

I definitely agree that validation is important, so your solution is ideal.  In the meantime (and for my needs), I created an external js object like this:

var Customer = function () {
 this.FirstName = '';
 this LastName = '';
};

Customer.prototype.FromJson = function(jsonString) {
 var jo = JSON.parse(jsonString);

 if (jo.FirstName) { this.FirstName = jo.FirstName; }
 if (jo.LastName) { this.LastName =  jo.LastName; }
};

IvrCustomer.prototype.ToJson = function(MakeReadable) {
 if (MakeReadable) {
   return JSON.stringify(this, null, 4);
 }
 else
 {
   return JSON.stringify(this);
 }
};

This way, missing/additional fields won't cause errors during deserialization.

Will the EWB 2 serialization mechanism have the option to ignore unknown fields?  This can be valuable for backward compatibility when a new/unknown field is added.

Thanks,
Doug

"Tim Young [Elevate Software]" wrote:

Doug,

<< TParser seems far too complicated when a JavaScript object supports
native parsing as per the above. >>

Yes, but how do you know that what you've parsed is what you *thought* you
were parsing ?   IOW, what happens if ServerData.Customer.Name isn't
actually defined because it didn't exist in the inbound JSON ?

EWB 2 will allow for saving/loading objects to/from JSON with a single call.
It still uses TParser, though, since using a parser allows for better
validation and simply avoids an additional step of having to iterate the
properties in the parsed objects and determine which properties exist, if
they're the correct type, etc.

Tim Young
Elevate Software
www.elevatesoft.com
Thu, Apr 16 2015 4:01 PMPermanent Link

Doug B

BTW, is there any way to edit posts for corrections?

Thanks,
Doug
Sat, Apr 18 2015 10:24 AMPermanent Link

Mark Brooks

Slikware

Avatar

"Tim Young [Elevate Software]" wrote:

>>EWB 2 will allow for saving/loading objects to/from JSON with a single call.

Hi Tim,

Hope you're well
.
Can you tell me what you mean by this statement please? In my EWB1 app I have a whole bunch of objects and created, for each, a LoadFromJSON method to parse JSON and populate properties accordingly. Is this partially automated in EWB2? That would be wonderful.

Regards
Mark
Mon, Apr 20 2015 4:33 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Doug,

<< Will the EWB 2 serialization mechanism have the option to ignore unknown
fields? >>

Yes, currently it always ignores unknown properties.

Tim Young
Elevate Software
www.elevatesoft.com
Mon, Apr 20 2015 4:34 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Doug,

<< BTW, is there any way to edit posts for corrections? >>

No, just add a new post with the correction.

Tim Young
Elevate Software
www.elevatesoft.com
Mon, Apr 20 2015 4:37 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Mark,

<< Hope you're well >>

Tired, but well, thank you. Smile

<< Can you tell me what you mean by this statement please? In my EWB1 app I
have a whole bunch of objects and created, for each, a LoadFromJSON method
to parse JSON and populate properties accordingly. Is this partially
automated in EWB2? That would be wonderful. >>

Yes, EWB2 can load the published properties for any TPersistent descendant
automatically from JSON.  It will be able to save it also, although I need
to add those bits back in (they got removed a few months back).

TPersistent looks like this:

  TPersistent = class
     protected
        procedure BeforeLoad; virtual;
        procedure AfterLoad; virtual;
        procedure LoadError(E: Exception); virtual;
        function LoadProperty(AReader: TReader): Boolean; virtual;
        procedure LoadProperties(AReader: TReader); virtual;
        procedure LoadObject(AReader: TReader); virtual;
        function LoadArrayElement(AReader: TReader): Boolean; virtual;
        procedure LoadArrayElements(AReader: TReader); virtual;
        procedure LoadArray(AReader: TReader); virtual;
        procedure BeforeSave; virtual;
        procedure AfterSave; virtual;
        procedure SaveError(E: Exception); virtual;
//         procedure SaveProperties(AWriter: TWriter); virtual;
//         procedure SaveArrayElements(AWriter: TWriter); virtual;
        procedure Load(AReader: TReader); virtual;
//         procedure Save(AWriter: TWriter); virtual;
//         procedure Assign(APersistent: TPersistent); virtual;
     end;

This is how a form loads itself at runtime:

procedure TFormControl.LoadFromResource;
begin
  {$IFNDEF DESIGN}
  FReader.RootComponent:=Self;
  FReader.Initialize(InterfaceManager.GetResource(SCRIPT_FORM_VALUE,ClassName),
                     InterfaceManager.GetResourceCompressed(SCRIPT_FORM_VALUE,ClassName));
  if FReader.IsObject then
     begin
     Load(FReader);
     FReader.ApplyFixups;
     end;
  {$ENDIF}
end;

EWB can do all sorts of cool RTTI stuff now, including creating components
by name, creating methods dynamically, etc.

Tim Young
Elevate Software
www.elevatesoft.com
Tue, Apr 21 2015 3:22 AMPermanent Link

Mark Brooks

Slikware

Avatar

"Tim Young [Elevate Software]" wrote:

>>Tired, but well, thank you. Smile

Ha! The price of victory!

>>Yes, EWB2 can load the published properties for any TPersistent descendant
>>automatically from JSON.  It will be able to save it also, although I need
>>to add those bits back in (they got removed a few months back).

Ok. My use case is a little different, but maybe not too much. One of the REST APIs that my EWB client talks to returns lots of data in JSON format. I have a large library of classes that I use to hold this data. Each class has its own  LoadFromJSON method which accepts a JSON string then uses a TParser instance to trawl through it and fill in the class properties. This works, but is incredibly painful to (a) maintain and (b) add to. Is there anything in EWB2, perhaps based on that capabilities you've outlined, that can populate the properties for a standard class from some JSON?
Page 1 of 3Next Page »
Jump to Page:  1 2 3
Image