How to work with 3rd-Party JSON data retrieved from XData in WEB Core?

I'm working with some 3rd-party APIs that return JSON data. When I call them directly from my VCL app, everything is fine. I put them into my XData service, and when I call them from VCL, I get back JSON data and can parse it with different parsers and that's fine. In fact, I created a class for each of these; I pass the JSON string to a factory method and it gives me back a class instance (usually a TList<something>) that contains the data I received.

However, when I call the XData services from my WebCore client and get back the TXDataClientResponse, I get the same JSON data, but I can't figure out how to parse it. The data is returned as

{ "value": {... JSON from 3rd-party site ...} }

I can get this 3rd-party JSON data as a string on the WEB Core client, but how do I work with it?

TXDataClientResponse.ResultAsObject and ResultAsArray return a TObject, but it's a JSON string.

TXDataClientResponse.Result is a Variant.

I can't use System.JSON or REST.JSON or superobject or any other JSON units in WEB Core.

I can't use the classes I created that work in VCL for the same reason: they use a JSON parser that won't compile in WEB Core.

Here's an example that I get as the "value":

{ "success": true, "data": { "voices_list": [ { "Engine": "neural", "VoiceId": "Jo", "VoiceGender": "Female", "VoiceWebname": "Jo", "Country": "US", "Language": "en-US", "LanguageName": "English, US" }, { "Engine": "neural", "VoiceId": "Ken", "VoiceGender": "Male", "VoiceWebname": "Ken", "Country": "US", "Language": "en-US", "LanguageName": "English, US" } ] } }

That's what I get from calling the XData service, both VCL and WEB Core. I can parse it in the VCL client, but I don't know what to do with it in the WEB Core client.

Maybe this is something I need to handle on the XData side? If so, how?

I've searched through the docs and can't find anything that relates to this in either the XData docs or the WEB Core docs.

Try in this way:

var respObject:TJSObject;

respObject:=toObject(Response.Result)['value'];

After that you will have respObject as JSON Object.

Again, I've already got the "value" -- the string associated with it is:

{ "success": true, "data": { "voices_list": [ { "Engine": "neural", "VoiceId": "Jo", "VoiceGender": "Female", "VoiceWebname": "Jo", "Country": "US", "Language": "en-US", "LanguageName": "English, US" }, { "Engine": "neural", "VoiceId": "Ken", "VoiceGender": "Male", "VoiceWebname": "Ken", "Country": "US", "Language": "en-US", "LanguageName": "English, US" } ] } }

Given this declaration:

type TJSObject = TObject;

casting this JSON string to TObject doesn't accomplish anything. It's a string, not an object.

This doesn't compile.

respObject:=toObject(Response.Result)['value'];
.................................
[Error] frmTest3Main.pas(308): Incompatible types: got "JSValue" expected "TJSObject"

This is what's defined in XData.Web.Client above TXDataClientResponse:

type
  JSValue = type Variant;
  TJSObject = type TObject;
  TJSArray = type TObject;
  TXDataWebClient = class;
  TXDataClientRequestType = (rtGet, rtList, rtPut, rtPost, rtDelete, rtRawInvoke);

  TXDataClientResponse = class
  . . .

All there is to work with is a Variant and a TObject. Assigning a string to JSValue (a variant) isn't causing it to be parsed as a JSON expression. So I'm still unclear how to parse this JSON expression in WEB Core.

try this.

uses JS, XData.Web.Client;

var
  lRetval: TXDataClientResponse;
  lResponseObject, lMyObject: TJSObject;
  lSuccess: Boolean;
begin
  lRetval := await(TXDataClientResponse, WebClient1.RawInvokeAsync('IMyService.MyFunction', [Var1, Var2]));

  lResponseObect := lRetval.ResultAsObject;

  lSuccess := JS.toBoolean(lResponseObject['success']);

  lMyObject := JS.toObject(lResponseObject['data']);

end;

Hello i had the same problem,

you can try this, its based upon an expample from holger flick out of his book. i changed it up in 2 steps to catch the object 'value' then i catched the array.
Then it worked... i got my data

procedure TForm1.WebHttpRequest1Response(Sender: TObject; AResponse: string);
var
JS: TJSON;
JA: TJSONArray;
JO, JOroot: TJSONObject;
i: integer;
begin
WebListBox1.Items.Clear;
js := tjson.Create;
try
joroot := tjsonobject(js.Parse(aResponse));
//ja := TJsonarray(js.Parse(aresponse));
showmessage(' Retrieve items:'+joroot.Count.ToString);
ja := TJsonarray(joroot.Items[0]);
showmessage(' Retrieve items:'+ja.Count.ToString);
for i := 0 to ja.Count-1 do begin
jo := tjsonobject(ja.Items[i]);
WebListBox1.Items.Add(jo.GetJSONValue('one of your var declaration'));
end;

finally
js.Free;
end;

2 Likes

I'd forgotten I had that book, TMS WEB Core. I dug it out and was going through it when you posted your reply. It demystifies all of this quite well.

1 Like