Hello,
in our project we use the TMS Web Core component TWebContinuousScroll.
We use it to fetch data from our REST server in the OnFetchNextPage event and insert this data into the scroll list in the OnGetData event.
To make sure all the data has arrived before OnGetData is called, we use an Async/Await combination to fetch the data.
This Async/Await combination works perfectly fine in many other places within our software, except in the OnFetchNextPage and/or OnGetData event handlers of the TWebContinuousScroll component.
If we use it there, TAwait.Exec does not work.
Case 1:
procedure xxxFetchNextPage(...);
begin
AURL := '';
end;procedure xxxOnGetData(...);
begin
if TAwait.Exec(DataModel.MachineAlarmList.LoadAsync(APageNumber, APageSize)) then
begin
// Read data from data model
MachineAlarms :=
TJSJSON.parseObject(TJSJSON.stringify(DataModel.MachineAlarmList.
MachineAlarms)).Properties['FItems'];
...
end;
Theoretically the data should be fetched first and then read out. In reality the data is fetched by LoadAsync and just before it is copied there into the data model, the line TJSJSON.parseObject (...) is already executed.
Unfortunately, however, at this point the data is not yet in the data model.
Case 2:
We move LoadAsync to xxxNextPage and leave parseObject in xxxGetData.
The problem remains.
Case 3:
We move LoadAsync to xxxGetData and leave parseObject in xxxGetData.
The problem remains.
Troubleshooting:
We debugged all the described sequences in the browser and found that Asysnc/Await is always interrupted when nested events are processed.
OnFetchNextPage calls internally OnGetData, OnGetData calls further OnXXX. And at the second nesting level, Async/Await no longer works.
Temporary solution:
If you look at the source code of TWebContinuousScroll, at some point you will come across the procedure ProcessResponseData .
This is ALWAYS called after all OnXXX handlers are processed and all data is available.
Unfortunately ProcessResponseData is protected, i.e. you can't use it "from outside".
After we've moved the function "ProcessResponseData" into the public area, the following source code was created, which now works properly:
procedure xxxFetchNextPage(...);
begin
// Get Data from REST Server and store it in data model …
if TAwait.Exec(DataModel.MachineAlarmList.LoadAsync(APageNumber, APageSize))
then begin// Read data from data model and store it in local variable MachineAlarms := TJSJSON.parseObject(TJSJSON.stringify(DataModel.MachineAlarmList. MachineAlarms)).Properties['FItems'];
// Move data from local variable to WebContiniousScroll Component
cscMachineAlarms.ProcessResponseData(TJSJSON.stringify(MachineAlarms));
end;procedure xxxOnGetData(...);
begin
// not used
end;
As you can see, all data transmission is handled in one single event handler, and et voila ... everything works fine.
Question/Request
Would it be possible to make the function "ProcessResponseData" public or provide another equivalent function , so that we can push data into the component even without cascaded OnXXXEvent calls ?
Many thanks in advance for your valuable support ...
Gerhard