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);
}
}