I am getting an intermittent exception in the console from the DOM:
Uncaught (in promise) Error: 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.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
I understand the error, ultimately I have an event driven component that is updated from the DOM/Client using javascript:
DotNet.invokeMethodAsync('onlymusik.com.Web', 'OnVideoEnded').then(data => {
console.log('OnVideoEnded, return: ' + data);
});
As I understand it, I am getting this error because my event handler is triggered before the OnAfterRenderAsync() event has completed. Below is my event handler in the component:
private static AudioPlayer? _instance;
[JSInvokableAttribute("OnVideoEnded")]
public static async Task<string> VideoEnded()
{
if (_instance != null)
{
await _instance.HandleVideoEnded();
return "Success: ";
}
return "No active AudioPlayer instance";
}
private async Task HandleVideoEnded()
{
// Prevent concurrent executions
await InvokeAsync(async () =>
{
await jsRuntime.InvokeVoidAsync("playerLog",$"HandleVideoEnded() InvokeAsync _isHandlingVideoEnded: {_isHandlingVideoEnded}");
});
if (_isHandlingVideoEnded)
return;
try
{
_isHandlingVideoEnded = true;
// Only use JS interop if we're not prerendering
if (!_isPrerendering)
{
await InvokeAsync(async () =>
{
isPlaying = false;
hasPlayed = true;
try
{
await jsRuntime.InvokeVoidAsync("playerLog", "HandleVideoEnded()");
await jsRuntime.InvokeVoidAsync("playerLog", "Preparing to play next track");
await PlayNextTrack();
await jsRuntime.InvokeVoidAsync("playerLog", "OnVideoEndedCallback.InvokeAsync");
await OnVideoEndedCallback.InvokeAsync(null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in HandleVideoEnded JS operations");
}
});
}
else
{
_logger.LogInformation("Skipping JS interop during prerendering in HandleVideoEnded");
}
}
finally
{
_isHandlingVideoEnded = false;
}
}
Without loads of boiler plate code that would queue events and replay them after the component has ended, is there anything glaringly obvious in my code where I might have missed the point with Blazor and Event Driven Architecture? Failing that, does anyone with experience with blazor event architecture have any advice?
Appreciated, thanks.