0

When ever refresh or manually navigate to a Blazor page that is using javascript interop, it errors out because the dispose function no longer exists in javascript.

Is there a way to not run "dispose" on a component that implements IDisposable when its a refresh or a navigation? Is there where the "ElementReference" type would help?

Here's some code for context:

My blazor component implements IDisposable:

@implements IDisposable

this runs my Dispose function, which calls on my interop file:

public void Dispose()
{
    JqxWindowJsInterop.Dispose();
}

my JsInterop runs this call to javascript:

public void Dispose()
    {
        jsRuntime.InvokeAsync<string>(
            "jqxWindowComponent.dispose",
            InstanceId);
        _JqxWindowJsInteropReference?.Dispose();
    }

which finally runs this in javascript:

window.jqxWindowComponent = {
dispose: function (instanceId) {
    console.log('jqxWindowComponent.dispose : ' + instanceId);
    if ($('#' + instanceId).length) {
        $('#' + instanceId).jqxWindow('destroy');
    }
    delete jqxWindowList[instanceId];       
}};

when I refresh or navigate to/from to this page through the browser I get this error

System.NullReferenceException: 'Object reference not set to an instance of an object.'MyNameSpace.Components.JqxWindowComponent.JqxWindowJsInterop.get returned null.

Any help appreciated.

16
  • What is the instanceId? Do you see if in the log files? Did you check log file? Commented Oct 29, 2020 at 17:53
  • I assign my JavaScript components a generated guid, passed as InstanceId Commented Oct 29, 2020 at 17:54
  • Did you remove the instanceId? Exception could be caused by the instance being deleted before the JaveScript is run. Commented Oct 29, 2020 at 17:58
  • The dispose removes the instance. It runs correctly when navigating using the Blazor site, just crashes when navigating manually with the browser URL Commented Oct 29, 2020 at 18:01
  • You may have a timing issue and just lucky it doesn't crash when running. The id may get deleted too early and you are only seeing issue when you step through slowly. Commented Oct 29, 2020 at 18:14

1 Answer 1

3

I was able to solve this by adding a render check property.

private bool firstRenderComplete;

I set it here:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        firstRenderComplete = true;
        DayPilotJsInterop = new DayPilotJsInterop(JavascriptRunTime, InstanceId);

        await DayPilotJsInterop.Initialize();
    }
}

and finally test it here:

public void Dispose()
{
    if(firstRenderComplete == true)
    {
        DayPilotJsInterop.Dispose();
    }

}
Sign up to request clarification or add additional context in comments.

1 Comment

to simplify you can just use if(firstRenderComplete) for true and if(!firstRenderComplete) for false.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.