Eduardo Fonseca
Eduardo Fonseca

Reputation: 575

Issue with RenderFragment in Blazor after leaving page with injected scripts

So, I've been learning how to create dynamic html in Blazor using RenderFragment, most the test have worked ok so far, except when generating html which injects javascript that modifies the end result. In this case I'm generating the scripts for the LinkedIn button

public RenderFragment RenderButton()
{
    RenderFragment form = b =>
    {
        if (this.AddPlatformScript)
        {
            b.OpenElement(1, "script");
            b.AddAttribute(1, "src", "https://platform.linkedin.com/in.js");
            b.AddAttribute(1, "type", "text/javascript");
            b.CloseElement();
        }
        b.OpenElement(2, "script");
        b.AddAttribute(2, "data-url", $"{this.UrlToShare}");
        b.AddAttribute(3, "type", "IN/Share");
        b.CloseElement();
    };
    return form;
}

The code to render the items is the following public RenderFragment UIFragment { get; private set; }

    protected override void OnInitialized()
    {
        this.UIFragment = this.RenderButton();
    }

The issue is that as soon as I leave that page I get the following error

**crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Cannot read property 'removeChild' of null
      TypeError: Cannot read property 'removeChild' of null
          at e (https://localhost:5001/_framework/blazor.webassembly.js:1:6918)
          at e (https://localhost:5001/_framework/blazor.webassembly.js:1:6890)
          at Object.e [as removeLogicalChild] (https://localhost:5001/_framework/blazor.webassembly.js:1:6890)
          at e.applyEdits (https://localhost:5001/_framework/blazor.webassembly.js:1:13649)
          at e.updateComponent (https://localhost:5001/_framework/blazor.webassembly.js:1:12880)
          at Object.t.renderBatch (https://localhost:5001/_framework/blazor.webassembly.js:1:1704)
          at Object.window.Blazor._internal.renderBatch (https://localhost:5001/_framework/blazor.webassembly.js:1:34784)
          at _mono_wasm_invoke_js_unmarshalled (https://localhost:5001/_framework/wasm/dotnet.3.2.0.js:1:172099)
          at wasm_invoke_iiiiii (https://localhost:5001/_framework/wasm/dotnet.wasm:wasm-function[3160]:0x9b33d)
          at icall_trampoline_dispatch (https://localhost:5001/_framework/wasm/dotnet.wasm:wasm-function[5777]:0xfe711)
Microsoft.JSInterop.JSException: Cannot read property 'removeChild' of null
TypeError: Cannot read property 'removeChild' of null
    at e (https://localhost:5001/_framework/blazor.webassembly.js:1:6918)
    at e (https://localhost:5001/_framework/blazor.webassembly.js:1:6890)
    at Object.e [as removeLogicalChild] (https://localhost:5001/_framework/blazor.webassembly.js:1:6890)
    at e.applyEdits (https://localhost:5001/_framework/blazor.webassembly.js:1:13649)
    at e.updateComponent (https://localhost:5001/_framework/blazor.webassembly.js:1:12880)
    at Object.t.renderBatch (https://localhost:5001/_framework/blazor.webassembly.js:1:1704)
    at Object.window.Blazor._internal.renderBatch (https://localhost:5001/_framework/blazor.webassembly.js:1:34784)
    at _mono_wasm_invoke_js_unmarshalled (https://localhost:5001/_framework/wasm/dotnet.3.2.0.js:1:172099)
    at wasm_invoke_iiiiii (https://localhost:5001/_framework/wasm/dotnet.wasm:wasm-function[3160]:0x9b33d)
    at icall_trampoline_dispatch (https://localhost:5001/_framework/wasm/dotnet.wasm:wasm-function[5777]:0xfe711)
  at Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled[T0,T1,T2,TResult] (System.String identifier, T0 arg0, T1 arg1, T2 arg2) <0x2cc84f0 + 0x00046> in <filename unknown>:0 
  at Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled[T0,T1,TResult] (System.String identifier, T0 arg0, T1 arg1) <0x2cc8410 + 0x00014> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer.UpdateDisplayAsync (Microsoft.AspNetCore.Components.RenderTree.RenderBatch& batch) <0x2cc8318 + 0x0001e> in <filename unknown>:0 
  at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue () <0x2b76b80 + 0x000f2> in <filename unknown>:0 
f.printErr @ blazor.webassembly.js:1
f.preRun.push.window.Blazor._internal.dotNetCriticalError @ blazor.webassembly.js:1
_mono_wasm_invoke_js_unmarshalled @ dotnet.3.2.0.js:1
do_icall @ dotnet.wasm:1
do_icall_wrapper @ dotnet.wasm:1
interp_exec_method @ dotnet.wasm:1
interp_runtime_invoke @ dotnet.wasm:1
mono_jit_runtime_invoke @ dotnet.wasm:1
do_runtime_invoke @ dotnet.wasm:1
mono_runtime_invoke_checked @ dotnet.wasm:1
mono_runtime_try_invoke_array @ dotnet.wasm:1
ves_icall_InternalInvoke @ dotnet.wasm:1
ves_icall_InternalInvoke_raw @ dotnet.wasm:1
do_icall @ dotnet.wasm:1
do_icall_wrapper @ dotnet.wasm:1
interp_exec_method @ dotnet.wasm:1
interp_runtime_invoke @ dotnet.wasm:1
mono_jit_runtime_invoke @ dotnet.wasm:1
do_runtime_invoke @ dotnet.wasm:1
mono_runtime_try_invoke @ dotnet.wasm:1
mono_runtime_invoke @ dotnet.wasm:1
mono_wasm_invoke_method @ dotnet.wasm:1
Module._mono_wasm_invoke_method @ dotnet.3.2.0.js:1
call_method @ dotnet.3.2.0.js:1
(anonymous) @ dotnet.3.2.0.js:1
beginInvokeDotNetFromJS @ blazor.webassembly.js:1
s @ blazor.webassembly.js:1
e.invokeMethodAsync @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
r @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
r @ blazor.webassembly.js:1
d @ blazor.webassembly.js:1
f @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
(anonymous) @ blazor.webassembly.js:1
e.onGlobalEvent @ blazor.webassembly.js:1

Does anyone knows how to prevent this from happening?

Upvotes: 1

Views: 1618

Answers (1)

Peter Morris
Peter Morris

Reputation: 23254

Blazor needs the generated html to remain unaltered or it can't find elements reliably to remove from the DOM.

If you want it to be altered you need to add it using AddMarkup passing in an instance of MarkupString that contains all the html you want your JS to be allowed to modify.

Upvotes: 2

Related Questions