Async component function not decorated async in output js

Ran into a problem with component development.

tldr;

The component offers a public async function like so:

Type
 TFooComp = Class(TComponent)
 Public
  [Async]
  Function Foo(Bar : String) : Boolean;
 End;

The main app uses this component and calls this:

  TAwait.Exec<Boolean>(FooComp1.Foo('bar'));

Compilation of the app fails with:

async function expected, but Result:Boolean found

Reason: the js of the compiled app has this

  rtl.createClass(this,"TFooComp",pas.Classes.TComponent,function () {
      this.Foo = function (Bar) {...

While it SHOULD read:

  rtl.createClass(this,"TFooComp",pas.Classes.TComponent,function () {
      this.Foo = async function (Bar) {...

=> The compiler fails to decorate the function as "async"

Long version:

Attached is everything needed to reproduce the problem. Best place to install is "C:\Temp\TMSCompBug" (change 2 paths in main app project settings when installing elsewhere) :

TMSCompBug.zip (89.7 KB)

Steps to reproduce:

  • In Delphi, open program group "CompBugGrp"

  • Compile and install TMSWebFooComp (this is the stub).
  • Compile and install TMSWEBFooCompWEB (this is the "real" component). Interesting enough, see that the component js file ("C:\Temp\TMSCompBug\Source\TMSWeb\Debug\WEBLib.FooComp.js") actually DOES have the async decorator.
  • Compile and run the main app CompBugTest
  • In the browser, open devtools
  • Reload the app (Ctrl-F5)
  • Watch the console showing this error

  • Open the main app js file ("C:\Temp\TMSCompBug\App\TMSWeb\Debug\CompBugTest.js")
  • Locate line: this.Foo = function (Bar) { (for me, this is line 56679)
  • Change line to read: this.Foo = async function (Bar) { (add the "async" decorator)
  • Save the file
  • In the browser, reload the app (Ctrl-F5)
  • No error is shown (click the button to see the async sleep working)

Try

 TFooComp = Class(TComponent)
 Public
  Function Foo(Bar : String) : Boolean; async;
 End;
1 Like

That did it!
It took me a day to figure the problem and what an easy solution there is!
I browsed every resource I know and couldn't find this easy solution.
The component development definitely needs some more documentation, in particular regarding this nasty issue.
Anyway, as usual, thanks a lot Bruno!

p.s. Use this to also make Delphi LSP happy
Function Foo(Bar : String) : Boolean; {$IFDEF PAS2JS} async; {$ENDIF}

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