I tried it and I read the documentation, but I am not able to solve it, sorry!
For a better understanding the whole procedure with the service all and the OnResponse procedure...
The content of Response.Result:
Do I have to define the fields? I tried it manually without a EntitySetValue. Afterwards I got a new error-message:
Uncaught TypeError: Cannot read property 'FAttributes' of null | TypeError: Cannot read property 'FAttributes' of null at Object.LoadData (http://localhost:8000/Web_App/Web_App.js:45609:113) at Object.ActiveChange (http://localhost:8000/Web_App/Web_App.js:45766:14) at Object.cb [as FOnActiveChange] (http://localhost:8000/Web_App/Web_App.js:222:26) at Object.ActiveChanged (http://localhost:8000/Web_App/Web_App.js:43368:46) at Object.CheckActiveAndEditing (http://localhost:8000/Web_App/Web_App.js:33702:14) at Object.DataEvent (http://localhost:8000/Web_App/Web_App.js:33766:14) at Object.DistributeEvent (http://localhost:8000/Web_App/Web_App.js:34021:44) at Object.ProcessEvent (http://localhost:8000/Web_App/Web_App.js:34045:12) at Object.DataEvent (http://localhost:8000/Web_App/Web_App.js:32534:52) at Object.SetState (http://localhost:8000/Web_App/Web_App.js:32989:14)
at http://localhost:8000/Web_App/Web_App.js [45609:113]
Your JSON contain several structures, this is how you should access the array (you can simplify this code of course using a single line, I have created several variables for better understanding:
var
JFDBS: TJSObject;
JManager: TJSObject;
JTableList: TJSObject;
JRowList: TJSArray;
..
JFDBS := TJSObject(TJSObject(Response.Result)['FDBS']);
JManager := TJSObject(JFDBS['Manager']);
JTableList := TJSObject(JManager['TableList']);
JRowList := TJSArray(JTableLlist['RowList']);
XDS_Abteilung.Close;
XDS_Abteilung.SetJsonData(JRowList);
Hi Wagner,
Uncaught TypeError: Cannot read property 'FDBS' of null | TypeError: Cannot read property 'FDBS' of null at OnResponse (http://localhost:8000/Web_App/Web_App.js:57008:62) at Object.DoLoad (http://localhost:8000/Web_App/Web_App.js:50388:11) at Object.DoLoad (http://localhost:8000/Web_App/Web_App.js:50662:20) at OnSuccess (http://localhost:8000/Web_App/Web_App.js:50778:19) at LocalSuccess (http://localhost:8000/Web_App/Web_App.js:50033:9) at XMLHttpRequest.XhrLoad (http://localhost:8000/Web_App/Web_App.js:50132:34)
at http://localhost:8000/Web_App/Web_App.js [57008:62]
I checked the function via swagger. May be the following message helps to understand what is happen:
First you need to make sure your server is returning correct data. Open your browser console and check the network tab to see what the server is returning when you are invoking the IData_xChangeService.Get_Abteilung method. This way we can focus either on client or server.
Queued at 0 | ||
Started at 0.96 ms | ||
Resource Scheduling | DURATION | |
Queueing | |
0.96 ms |
Connection Start | DURATION | |
Stalled | |
0.57 ms |
Request/Response | DURATION | |
Request sent | |
69 μs |
Waiting (TTFB) | |
1.91 ms |
Content Download | |
0.47 ms |
Explanation | 3.97 ms |
Is that helpful for you?
JFDBS := TJSObject(TJSObject(TJSJson.Parse(string(Response.Result)))['FDBS']);
JManager := TJSObject(JFDBS['Manager']);
JTableList := TJSObject(TJSArray(JManager['TableList'])[0]);
JRowList := TJSArray(JTableList['RowList']);
console.log(JRowList);
JFDBS := TJSObject(TJSObject(TJSJson.Parse(string(Response.Result)))['FDBS']);
JManager := TJSObject(JFDBS['Manager']);
JTableList := TJSObject(TJSArray(JManager['TableList'])[0]);
JRowList := TJSArray(JTableList['RowList']);
console.log(JRowList);
"RowList": [{
"RowID": 0,
"Original": {
"AbteilungsID": 10,
"Abteilung": "Verkauf",
"Test": "0"
}
},
I implemented all procedures you discuss and my fiinal code on client application is below. But i have a error 'entitysetname not set ' . What i'm wrong ?
In Response.ResponseText there is a JSON string with all data...
procedure TfrmPrestMac.btPrestClick(Sender: TObject);
procedure OnResponse(Response: TXDataClientResponse);
Var JFDBS: TJSObject; JManager: TJSObject; JTableList: TJSObject; JRowList: TJSArray;
begin
JFDBS := TJSObject(TJSObject(TJSJson.Parse(string(Response.Result)))['FDBS']);
JManager := TJSObject(JFDBS['Manager']);
JTableList := TJSObject(TJSArray(JManager['TableList'])[0]);
JRowList := TJSArray(JTableList['RowList']);
showmessage(Response.ResponseText);
//showmessage(js.ToString(JRowList));
wdPrest.Close();
//wdPrest.entitysetname:=js.ToString(JTableList);
wdPrest.SetJsonData(JRowList);
wdPrest.Open();
end;
begin
wdcPrest.RawInvoke(
'IMyQueryService.DoQuery',['',
'SELECT Azione, Data_Ora, TDS_Reg, Info_Cli FROM SMS_Act WHERE TDS_Reg > 200'],
@OnResponse);
end;
I created persistent fields and now go ... BUT now grid show me the rows of the records but they are Empty !! there is a wrong type data ?
Yes, you need to create persistent fields manually if you don't set EntitySetName
.
As for grid being empty, inspect the request result and the objects if your code in OnResponse
tries to read one single property wrongly, the result would be null. Make sure you are reading the returned JSON structure correctly.
persistent fields manually
by code ex. I need to put Original before ?
wdPrest.Close();
wdPrest.FieldDefs.Clear;
wdPrest.FieldDefs.Add('Original.Azione',ftString,5);
wdPrest.FieldDefs.Add('Original.Data_Ora',ftString,20);
wdPrest.FieldDefs.Add('Original.TDS_Reg',ftString,10);
wdPrest.FieldDefs.Add('Original.Info_Cli',ftString,200);
wdPrest.SetJsonData(JRowList);
wdPrest.Open();
But if i create field by code give me EntitySetName
.dont set ...
if i create at design time fields dont give me error of EntitySetName
but all records in grid are empty. I must put original in it ? where ? give me a cant find field ...
You should create the fields at design-time, at least to understand what's going on.
I can't tell why your grid is empty, your code looks correct according to the grid. Then I could only give you more information if I have more information, preferable a small sample project that reproduces the issue.
I'd like to add another voice to Guido's post...
If I have an XDataWebDataset dropped on a form, and then create fields at design time, and then try to populate it with the SetJsonData function, it works.
If I instead create the fields for the same control using FieldDefs at runtime, it seems to think it still needs the EntitySetName set and thus fails.
I think what he's trying to do (and what I'm trying to do) is to have a local TDataset that contains the records coming from something like an FDQuery on the server, without using the Entity mechanism but rather a service call. And as we can't use a local TFDMemTable (for reasons that are not clear to me), the XDataWebDataset seems the closest thing, particularly with the SetJsonData function beign availabe. But for this to work we need to be able to define the fields at runtime and do everything else without actually using the connectivity aspects of the XDataWebDataset in this instance as we're supplying the data after having gotten it (manually) via Json previously.
If there is a dummy field added at runtime then the error is different (can't find matching fields) so presumably there's a problem in XDataWebDataset's handling of FieldDefs. Maybe they're just not iimplemented?
Perhaps I can writeup an issue that more clearly shows the process from having an FDQuery dump data into a TStream on an XData endpoint and then having it recreated locally so it can be used in a local WebDBGrid or available in the usual TDataSet First/Next kind of mechanism. With the TStream and its JSON contents being used as a simple communications mechanism without having to pay much attention to how it works.
There is no "memory dataset" in Web Core because there is no direct memory access in JavaScript. It doesn't make sense.
TXDataWebDataset
is indeed the correct "memory dataset" you can get in Web Core, because it supports JavaScript objects and primitive values, which is the closes you can get as "memory".
All you need to do is input raw data using SetJsonData
, as you do. But of course you have to have your fields defined in advance, to tell the dataset which data from the objects you want to be treated as dataset field. Yes, I think more detail about what you are trying to achieve would be needed.