Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delay JSInterop until after prerender #18

Closed
TLabWest opened this issue Apr 6, 2021 · 2 comments
Closed

Delay JSInterop until after prerender #18

TLabWest opened this issue Apr 6, 2021 · 2 comments

Comments

@TLabWest
Copy link

TLabWest commented Apr 6, 2021

In a Blazor-Server setup I get the following error during startup:

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 Blazor.IntersectionObserver.IntersectionObserverService.DisposeAsync()
         at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.<DisposeAsync>g__Await|15_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)

To reproduce the error, simply add the <IntersectionObserve> component to a Blazor (.razor) component and launch the Blazor Server app. Unfortunately I don't have a small repro project right now, I could get back to you with one should it still be needed.

NB: It still works, it's just flooding my error log with unsightly call stacks. I have worked around the problem by flagging a bool in my own OnAfterRenderAsync() and only including the <IntersectionObserve> component conditionally when that flag is set. Still, this should probably be handled more centrally in the IntersectionObserve component itself.

More information and simple examples can be found here: https://docs.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-5.0#detect-when-a-blazor-server-app-is-prerendering

@ljbc1994
Copy link
Owner

Hi @TLabWest,

Thanks for raising this, I can replicate but I think it's to do with the initial import of the observer js which occurs when the service is initialised.

The <IntersectionObserve> component does check to initialise the observer after render:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await this.InitialiseObserver();
    }
}

Will be looking into this and let you know when it's been fixed.

Thanks!

@ljbc1994
Copy link
Owner

This is fixed in the latest release #23, however it does contain a breaking change in relation to the component so please be aware of that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant