Warning about TStringList error in Delphi

While getting to know the SmartUI components, I ran into something I didn't expect.
The SmartUI Sample was working perfectly for me last month, both in Delphi and VSC.
Last weekend I opened the sample project in Delphi 11.3 and it throws an error, the red kind one.
Using the same SmartUI component versions and code, the app runs perfectly in Visual Studio Code.
I traced the error to a line where it gets data from a TStringList.
It seems that in the same step in the program, the Delphi code seems to lose the TStingList length and .count is undefined, so the program fails. In the sample there are 99 lines inserted into the TStringList (component s1).
Tracing the same in VSC, the TstringList holds it's contents and the program does not fail.

The only difference I have is that for VSC the installed WebCore Version is from Oct. 28, 2022 whereas for Delphi the version is from Apr. 4, 2023.
I made a small test with a single TStringList and could not reproduce the problem, but it is consistent in the SmartUI demo, so it could be related to deeper issues with all the dynamic variables being created.
Now, I said "Warning" because it was working in Delphi before and now I think that a new version for VSC could carry the problem on.
The screenshot attached has an arrow marked where the program fails to retrieve data from s1[I]. At the end of the loop where the data is being added with s1[cnt], the TStringList is full of data yet.

2023-04-11 08_06_54-SmartUIDemo - Delphi 11 - Unit1 Built

BTW, SmartUI versions between Delphi and VSC were the same for this tests, and tried with versions 12,13 and 15, with same consistent results.


We cannot reproduce this just by opening and running the demo (tried both Debug and Release configurations).

You said it was working fine a month ago. Were you using 11.3 then or was it a different version?

Did you modify the demo in any way (project or component settings) that could mean a difference?

I apologize. So far I assumed that Delphi could not be the cause, but you are right, I installed 11.3 a couple of weeks ago, and the latest patch just yesterday. So, delphi version is another factor to consider.
Guess the only way of having proof is either upgrading Delphi on your side or downgrading in my side.

The SmartUI demo was not modified at all, other than commenting the lines marked with an arrow for my tests. I created two additional copies of the whole original demo, and put the different versions of SmartUI js and css to have separate tests.

The IDE version actually should not really matter as long as WEB Core was properly installed - I was just trying to figure out what steps lead you to this state.

Can you confirm your current version is reported as by taking a look at the version number in Help > About TMS WEB Core and the compiler output when you compile the project?

You mentioned no modifications to the project - am I understanding correctly you are running the demo with the Debug configuration selected (just to rule out any optimization that could've gone wrong)?

The compiler shows that version number and the help about too. The build is debug and the project does not have optimization or obfuscation enabled.

To retrace my steps, I just downloaded again the components and pulled the demo folder to run the test. I copied smart.elements.js and smart.default.css to the folder project and added them to the project. Also added the link and script to the project's html.

I took a dual screen's screenshot where you can see all mentioned above, plus the full error in console. The error goes away if I comment the lines mentioned in my first post, where the Smart Listbox adds items from the stingList sl. There is no error in this case, but the Countries Listbox is empty.

Thank you, we finally managed to reproduce this.

The issue is actually not the TStringList but the Smart UI element that is not initialized in time for some reason so the insert() call fails on the undefined _items. In our case this only happens on our Windows 11 machine - was it working for you with Windows 11 before? Did any updates happen between the working and non-working state?

Every once in a while it initializes without problems but most of the time the error appears. We can actually see the same behavior in our online demo we published almost 3 years ago (obviously made with a completely different TMS WEB Core, compiler and Delphi version). If you keep refreshing, sometimes the country list remains empty. You can check it by clicking here.

We'll investigate this to see if there's something we can do to improve the initialization of the element.

Unfortunately it looks like the components are initialized (by the library) when the window.onload event is triggered. If the TWebForm.OnCreate event is called before that and the HTTP request is finished before the window.onload has a chance to trigger, then we are left with this error. There's not much we can do about this within the component(s) as we'd need to persist each call that happens before the component is initialized by the library and then execute them once the window.onload happens - that's simply not feasible.

Alternatively, the demo can be changed in one of the two following ways to make sure the component is interacted with after window.onload:

  1. Execute the HTTP request after window.onload:
procedure TForm1.WebFormCreate(Sender: TObject);
  procedure GetCars;
    if window.document.readyState = 'complete' then
      window.setTimeout(@GetCars, 100);
  FSelectedIndexes := [];
  FMaxSpeed := 0;
  FMaxPrice := 0;
  window.setTimeout(@GetCars, 0);
  1. Execute the HTTP request as usual but wait with adding the elements dynamically:
procedure TForm1.WebHttpRequest1Response(Sender: TObject; AResponse: string);
  procedure AddElements;
    if window.document.readyState = 'complete' then
      window.setTimeout(@AddElements, 100);
  jsonClass: TJSON;
  jsonClass := TJSON.Create;
  json := TJSONArray(jsonClass.parse(AResponse));

  window.setTimeout(@AddElements, 0);

We'll update the demo accordingly and keep an eye out for improvements.

Is always good to find the bug, thanks :slight_smile:

As for windows 11 updates, yes, there has been been some, I've lost count. Both Microsoft and Dell updates are constantly asking to install and sometimes restart the computer.

I do remember the SmartUI component update, I think it was back in September, after I posted a report that it was not working with the new WebCore versions.

Is the component initialization related to the console log that reads "Element does not exist in the DOM" ?

It seems I replied before your second answer. Thanks for the info, is very useful.
Perhaps an alternative is to make the component as part of the template, but in that case it can be handled via javascript in asm statements. Will try that.

Other approach to have a faster load could be to use single component js files instead of the full smart.elements.js, which is kind of large for a js library.

Taking advantage of the demo revision you mentioned, is it possible that you create a simple demo on how to use the SmartGrid and SmartTable? or perhaps some general guide from the delphi perspective? Since the jqwidgets site is well documented, I was planning to include them with the javascript approach but it would be just perfect to use them fully in delphi, however, here is not any documentation for them other than how to run the demo.

Yes, and that is what eventually lead to window.onload.
When WebSmartListBox1.Insert is called, it maps onto the insert() function of the given SmartUI element. The problem is, when this insert() is being invoked, the window.onload event is not yet fired for some reason. Invoking insert() before window.onload will cause that message to be logged to the console.

Maybe it's worth testing out to see if it has any improvements.

This is not in our planning for now but we can put it on our list for discussion.