Reputation: 4198
Hi I have a question about using Blazor and typescript.
My typescript:
namespace JSInteropWithTypeScript {
export class Generator {
public showAlert(): void {
alert("INTEROP");
}
}
export function Load(): void {
window['generator'] = new Generator();
}
}
JSInteropWithTypeScript.Load();
And here is generated JS:
var JSInteropWithTypeScript;
(function (JSInteropWithTypeScript) {
var Generator = /** @class */ (function () {
function Generator() {
}
Generator.prototype.showAlert = function () {
alert("INTEROP");
};
return Generator;
}());
JSInteropWithTypeScript.Generator = Generator;
function Load() {
window['generator'] = new Generator();
}
JSInteropWithTypeScript.Load = Load;
})(JSInteropWithTypeScript || (JSInteropWithTypeScript = {}));
JSInteropWithTypeScript.Load();
//# sourceMappingURL=generator.js.map
Next I want to call compiled js script so I have a simple component with button:
@namespace Components.Reports.Components.Generator
@inherits ControlsBase
<button class="btn btn-success" @onclick="ShowAlert"> BUTON </button>
In base class for this component I want to lazy load (so i do not need to add every script in _Host just use them when they are needed) this script file and call this function, so I made this contraption:
public class ControlsBase : ComponentBase, IAsyncDisposable
{
private readonly Lazy<Task<IJSObjectReference>> moduleTask;
[Inject]
protected IJSRuntime JsRuntime { get; set; }
public ControlsBase()
{
Task<IJSObjectReference> jsInvokes() => this.JsRuntime.InvokeAsync<IJSObjectReference>("import", "./_content/Components/js/generator.js").AsTask();
this. moduleTask = new Lazy<Task<IJSObjectReference>>(jsInvokes);
}
public async Task ShowAlert()
{
try
{
var module = await moduleTask.Value;
await module.InvokeVoidAsync("showAlert");
}
catch (JSException jsException)
{
logger.Error($"Problem with js interop {jsException}");
}
}
public async ValueTask DisposeAsync()
{
if (moduleTask.IsValueCreated)
{
var module = await moduleTask.Value;
await module.DisposeAsync();
}
}
}
So now I want to call this, my problem/question is when I call compiled js script I am getting
Could not find 'showAlert' ('showAlert' was undefined).
When i use vanilla code like:
export function showAlert() {
alert("INTEROP");
}
it works.
So what am I doing wrong with typescript?
EDIT
Using @Haytam guide I remade my ts to simple:
namespace JSInteropWithTypeScript {
export class Generator {
public ShowAlert(): void {
alert("INTEROP");
}
}
}
function showAlert(): void {
let generator = new JSInteropWithTypeScript.Generator();
generator.ShowAlert();
}
And it compiles to js:
var JSInteropWithTypeScript;
(function (JSInteropWithTypeScript) {
var Generator = /** @class */ (function () {
function Generator() {
}
Generator.prototype.ShowAlert = function () {
alert("INTEROP");
};
return Generator;
}());
JSInteropWithTypeScript.Generator = Generator;
})(JSInteropWithTypeScript || (JSInteropWithTypeScript = {}));
function showAlert() {
var generator = new JSInteropWithTypeScript.Generator();
generator.ShowAlert();
}
But to work properly I need to manually add export before function in js.I know that the cause for this error is that TypeScript, by default, produces JavaScript code that is designed for use through various package managers that cater to the exports and modules. Such tools are usully Node.js or WebPack. I can turn it off by using tsconfig:
{
"compilerOptions": {
"module": "none"
}
}
But still js interop works only when function is marked as export in js. Any ideas how to handle that?
EDIT2:
I think problem lays in lazy loding, added generated js script as static resource:
<script src="_content/Components/js/generator.js"></script>
and used code:
public async Task OnClick()
{
try
{
await this.JsRuntime.InvokeVoidAsync("showAlert");
}
catch (JSException jsException)
{
logger.Error($"Problem with js interop {jsException}");
}
}
In my component base and it is alive, but still just for curiosity I want to make n this lazy loading. Any suggestions would be appreciated.
Upvotes: 1
Views: 2339
Reputation: 4733
I see two problems here:
window
is not required anymore, that's why they added this isolation in the first place.I think you should try to export the functions directly.
EDIT
Based on your latest edit, doesn't this work?
export function showAlert(): void {
let generator = new JSInteropWithTypeScript.Generator();
generator.ShowAlert();
}
Upvotes: 1