OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Blazor server side application throwing "System.InvalidOperationException: JavaScript interop calls cannot be issued at this time. ..." during reload

  • Thread starter Thread starter Roland Deschain
  • Start date Start date
R

Roland Deschain

Guest
I have a file drop zone implemented in one of the pages of my blazor application, which is handled using the javascript runtime interface. In order to avoid memory leaks, I have a javascript method, which removes all the event listeners. This is called from the dispose function as follows:

Code:
public ValueTask DisposeAsync()
{
    ViewModel.PropertyChanged -= OnPropertyChangedHandler;
    GC.SuppressFinalize(this);
    return JSRuntime.InvokeVoidAsync("deInitializeDropZone");
}

This works, however if I reload the page in my browser (F5, or reload button), I get the following exceptions:

Code:
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HMI59N5RRGP7", Request id "0HMI59N5RRGP7:0000000E": An unhandled exception was thrown by the application.
      System.InvalidOperationException: JavaScript interop calls cannot be issued at this time. This is because the component is being statically rendered. When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.
         at Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSRuntime.BeginInvokeJS(Int64 asyncHandle, String identifier, String argsJson, JSCallResultType resultType, Int64 targetInstanceId)
         at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, CancellationToken cancellationToken, Object[] args)
         at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)
         at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args)
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.<>c__DisplayClass69_0.<<Dispose>g__HandleAsyncExceptions|1>d.MoveNext()
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.HandleException(Exception exception)
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.<>c__DisplayClass69_0.<Dispose>g__NotifyExceptions|2(List`1 exceptions)
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.<>c__DisplayClass69_0.<<Dispose>g__HandleAsyncExceptions|1>d.MoveNext()
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.DisposeAsync()
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.<DisposeAsync>g__Await|22_0(Int32 i, ValueTask vt, List`1 toDispose)
         at Microsoft.AspNetCore.Http.Features.RequestServicesFeature.<DisposeAsync>g__Awaited|9_0(RequestServicesFeature servicesFeature, ValueTask vt)
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.<FireOnCompleted>g__ProcessEvents|227_0(HttpProtocol protocol, Stack`1 events)
warn: Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100]
      Unhandled exception rendering component: JavaScript interop calls cannot be issued at this time. This is because the circuit has disconnected and is being disposed.
      Microsoft.JSInterop.JSDisconnectedException: JavaScript interop calls cannot be issued at this time. This is because the circuit has disconnected and is being disposed.
         at Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSRuntime.BeginInvokeJS(Int64 asyncHandle, String identifier, String argsJson, JSCallResultType resultType, Int64 targetInstanceId)
         at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, CancellationToken cancellationToken, Object[] args)
         at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)
         at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args)
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.<>c__DisplayClass69_0.<<Dispose>g__HandleAsyncExceptions|1>d.MoveNext()
fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
      Unhandled exception in circuit 'blLlOrw1UtfEHUoPBbO_N3peh7u3Or5Uk51p5RbR5xA'.
      Microsoft.JSInterop.JSDisconnectedException: JavaScript interop calls cannot be issued at this time. This is because the circuit has disconnected and is being disposed.
         at Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSRuntime.BeginInvokeJS(Int64 asyncHandle, String identifier, String argsJson, JSCallResultType resultType, Int64 targetInstanceId)
         at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, CancellationToken cancellationToken, Object[] args)
         at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)
         at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args)
         at Microsoft.AspNetCore.Components.RenderTree.Renderer.<>c__DisplayClass69_0.<<Dispose>g__HandleAsyncExceptions|1>d.MoveNext()

This will only happen on reload, if I switch to another page, the dispose function is called as well, but no exception. I'm not entirely sure what the reason for this problem is. Maybe it could relate to the initialization as well, which happens after first render:

Code:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        var authState = await AuthenticationStateTask;
        var user = authState.User;

        if (user.Identity.IsAuthenticated)
        {
            if (await ViewModel.LoadSelectedDatabase(DatasetID))
            {
                await JSRuntime.InvokeVoidAsync("initializeDropZone");
            }
            else
            {
                await JSRuntime.InvokeVoidAsync("alert", "The selected Dataset does not exist!");
                NavigationManager.NavigateTo($"datasets");
            }
        }
    }

    await base.OnAfterRenderAsync(firstRender);

    return;
}

Edit: Some more testing, exception is thrown before the await JSRuntime.InvokeVoidAsync("initializeDropZone"); is called after reload.

Edit#2: I also switched up the JS function:

Code:
public ValueTask DisposeAsync()
{
    ViewModel.PropertyChanged -= OnPropertyChangedHandler;
    GC.SuppressFinalize(this);

    return JSRuntime.InvokeVoidAsync("console.log", "testilein");
    //return JSRuntime.InvokeVoidAsync("deInitializeDropZone");
}

This will result in the same errors on reload.

<p>I have a file drop zone implemented in one of the pages of my blazor application, which is handled using the javascript runtime interface. In order to avoid memory leaks, I have a javascript method, which removes all the event listeners. This is called from the dispose function as follows:</p>
<pre><code>public ValueTask DisposeAsync()
{
ViewModel.PropertyChanged -= OnPropertyChangedHandler;
GC.SuppressFinalize(this);
return JSRuntime.InvokeVoidAsync("deInitializeDropZone");
}
</code></pre>
<p>This works, however if I reload the page in my browser (F5, or reload button), I get the following exceptions:</p>
<pre><code>fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HMI59N5RRGP7", Request id "0HMI59N5RRGP7:0000000E": An unhandled exception was thrown by the application.
System.InvalidOperationException: JavaScript interop calls cannot be issued at this time. This is because the component is being statically rendered. When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.
at Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSRuntime.BeginInvokeJS(Int64 asyncHandle, String identifier, String argsJson, JSCallResultType resultType, Int64 targetInstanceId)
at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, CancellationToken cancellationToken, Object[] args)
at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)
at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.<>c__DisplayClass69_0.<<Dispose>g__HandleAsyncExceptions|1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Components.Rendering.HtmlRenderer.HandleException(Exception exception)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.<>c__DisplayClass69_0.<Dispose>g__NotifyExceptions|2(List`1 exceptions)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.<>c__DisplayClass69_0.<<Dispose>g__HandleAsyncExceptions|1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Components.RenderTree.Renderer.DisposeAsync()
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.<DisposeAsync>g__Await|22_0(Int32 i, ValueTask vt, List`1 toDispose)
at Microsoft.AspNetCore.Http.Features.RequestServicesFeature.<DisposeAsync>g__Awaited|9_0(RequestServicesFeature servicesFeature, ValueTask vt)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.<FireOnCompleted>g__ProcessEvents|227_0(HttpProtocol protocol, Stack`1 events)
warn: Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100]
Unhandled exception rendering component: JavaScript interop calls cannot be issued at this time. This is because the circuit has disconnected and is being disposed.
Microsoft.JSInterop.JSDisconnectedException: JavaScript interop calls cannot be issued at this time. This is because the circuit has disconnected and is being disposed.
at Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSRuntime.BeginInvokeJS(Int64 asyncHandle, String identifier, String argsJson, JSCallResultType resultType, Int64 targetInstanceId)
at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, CancellationToken cancellationToken, Object[] args)
at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)
at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.<>c__DisplayClass69_0.<<Dispose>g__HandleAsyncExceptions|1>d.MoveNext()
fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
Unhandled exception in circuit 'blLlOrw1UtfEHUoPBbO_N3peh7u3Or5Uk51p5RbR5xA'.
Microsoft.JSInterop.JSDisconnectedException: JavaScript interop calls cannot be issued at this time. This is because the circuit has disconnected and is being disposed.
at Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSRuntime.BeginInvokeJS(Int64 asyncHandle, String identifier, String argsJson, JSCallResultType resultType, Int64 targetInstanceId)
at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, CancellationToken cancellationToken, Object[] args)
at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)
at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.<>c__DisplayClass69_0.<<Dispose>g__HandleAsyncExceptions|1>d.MoveNext()
</code></pre>
<p>This will only happen on reload, if I switch to another page, the dispose function is called as well, but no exception.
I'm not entirely sure what the reason for this problem is. Maybe it could relate to the initialization as well, which happens after first render:</p>
<pre><code>protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
var authState = await AuthenticationStateTask;
var user = authState.User;

if (user.Identity.IsAuthenticated)
{
if (await ViewModel.LoadSelectedDatabase(DatasetID))
{
await JSRuntime.InvokeVoidAsync("initializeDropZone");
}
else
{
await JSRuntime.InvokeVoidAsync("alert", "The selected Dataset does not exist!");
NavigationManager.NavigateTo($"datasets");
}
}
}

await base.OnAfterRenderAsync(firstRender);

return;
}
</code></pre>
<p><strong>Edit</strong>: Some more testing, exception is thrown before the <code>await JSRuntime.InvokeVoidAsync("initializeDropZone");</code> is called after reload.</p>
<p><strong>Edit#2</strong>: I also switched up the JS function:</p>
<pre><code>public ValueTask DisposeAsync()
{
ViewModel.PropertyChanged -= OnPropertyChangedHandler;
GC.SuppressFinalize(this);

return JSRuntime.InvokeVoidAsync("console.log", "testilein");
//return JSRuntime.InvokeVoidAsync("deInitializeDropZone");
}
</code></pre>
<p>This will result in the same errors on reload.</p>
 

Latest posts

Top