From TXDataClientResponse to TWebClientDataSet.Rows


i didn't want to write this, but it's 4 days that i'm stuck on this. I've made 1000 tests, read every topic on this forum, compiled and analyzed every demo. The problem is:

  1. I call a service via RawInvoke (all fine)
  2. on server, i execute a query, and i create a json stream with records. I use Firedac / TFDBatchMove / TFDBatchMoveJSONWriter, to generate a "standard" Json stream. The stream is apparently correct (i save it also on file, to see it)
  3. on client, in an event OnResult(Response: TXDataClientResponse), i try to achieve the goal to have the records in a TWebClientDataSet, and i fail miserably. Response.Result is filled with my json stream, i can see it in dbugger.

So, first question: the only way to convert Response.Result to a TJSArray that makes "val" variable filled is

procedure OnResult(Response: TXDataClientResponse);
val: TJSArray;
val := TJSArray( TJSJSON.parseObject( TJSJSON.stringify(Response.Result) ) );

is this correct ? There is a simpler way ? I've tried all, only this seems to work. All other tries , inspired by demos and forum topics, leave the val variable empty.

Second: with fields defined at design time in TWebClientDataSet, when i make

WebClientDataSet.Rows := val;

i have the error TypeError: Cannot read property 'Myfield' of null at Object.GetJSONDataForField

("Myfield" is the first field of the dataset). I suppose that i'm converting the Json stream in a wrong way, but i just can't find the right.

So, i need help... Thank you


A little note... i've come to that instruction

val := TJSArray( TJSJSON.parseObject( TJSJSON.stringify(Response.Result) ) );

because this one works correctly, i can see the record in a WebDbGrid

WebClientDataSet.Rows := TJSArray(TJSJSON.parseObject('[{"ID":1,"MESE":1,"ANNO":2020,"TOTPRES":27883}]') );

You can simply use it this way:

val := TJSArray(Response.Result);

Regarding your second question, I could only answer it if I see the actual JSON you are receiving from the RawInvoke response. Remember that JSON is case-sensitive.

Thank you Wagner,

at least i've understood that the problem is with the Json response, because with the debugger i see that val is null, after

val := TJSArray(Response.Result);

In this case i have no error with fileds, cause there is no Json to load.

This is the last Json generated

How is your server-side method signature declared? What is the exact response coming from the request (you can see in your network tab).
It's strange that FResult seems to be coming as string, instead of a JSON array.

Wagner, if you refer to the Service Contract, it's this

IEseguiSqlService = interface(IInvokable)
function Sum(A, B: double): double;
function EseguiSqlCode( codice: string): TStream;

function TEseguiSqlService.EseguiSqlCode( codice: string): TStream;
LResult: TMemoryStream;
LResult := TMemoryStream.Create;

ApiServer.EseguiSqlCode(codice, lresult );

Result := LResult;

.... maybe it's the TStream return type that cause the problem ?

this is the exact Response for the request

Yes, indeed the reason is the TStream result, which will cause the response to be in text format. In this case, you can use what you're doing, with a slight modification:

val := TJSArray(TJSJSON.parse(String(Response.Result)));

Thank you Wagner, now it works. I could have made another 1000 tries, without discovering this simple instruction....

I made that TStream result following this tutorial of Holger Flick. Now i know that i've misunderstood what he was trying to explain.

I think that i have to discover how to return a better structured Result, but this is another story.

Thank you Wagner, Happy Christmas to everybody at TMS !

1 Like

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.