Home > Mobile >  OnClick show/hide google maps div element in Blazor WASM
OnClick show/hide google maps div element in Blazor WASM

Time:09-17

I want to show/hide the map on button click action. I tried to achieve this by setting a bool variable which I set/reset in the on click action and check it in the razor page like in the example below:

        [Inject]
        public IJSRuntime JSRuntime { get; set; }

        protected bool displayMap = false;

        protected async Task OpenMap()
        {
            displayMap = !displayMap;
            if (displayMap)
            {
                await JSRuntime.InvokeVoidAsync("initialize", null);
            }
        }
            @if (displayMap)
            { 
                <MudCard>
                    <MudCardContent>
                        <div id="map" style="height:500px;width:100%;">
                        </div>
                    </MudCardContent>
                </MudCard>
            }

But seems like this solution won't work, because I get a rendering error:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] Unhandled exception rendering component: Map: Expected mapDiv of type Element but was passed null. Error

Seems like the initialize function is called before the div is rendered, but I don't know how to fix this problem. Please help!

CodePudding user response:

When you want to maintain map state between show/hide then instead of

@if (displayMap)
{ 
    <MudCard>
        <MudCardContent>
            <div id="map" style="height:500px;width:100%;">
            </div>
        </MudCardContent>
    </MudCard>
}

You can use

<MudCard hidden="@(!displayMap)">
    <MudCardContent>
        <div id="map" style="height:500px;width:100%;">
        </div>
    </MudCardContent>
</MudCard>

in combination with

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await JSRuntime.InvokeVoidAsync("initialize", null);
    }
}

and remove the await JSRuntime.InvokeVoidAsync(...) line from the button click.

CodePudding user response:

The problem is that after you set displayMap=true the Blazor UI is not immediately re-rendered so that when the JS initialize() function looks for #map it finds nothing.

Seems like the initialize function is called before the div is rendered

Exactly.

The easy fix:

protected async Task OpenMap()
{
    displayMap = !displayMap;
    if (displayMap)
    {
        await Task.Delay(1);  // allow the Render to happen
        await JSRuntime.InvokeVoidAsync("initialize", null);
    }
}
  • Related