I have a question with a setup of one of my components that relies heavily on JSInterop. The component contains a Google map and all of my data for initializing and displaying data on that map needs something from JSInterop. I was loading the data in a model inside OnInitializedAsync like I would normally do and then doing all of my JSInterop inside OnAfterRenderAsync. This worked fine with InteractiveAuto but when I refresh the browser and turn to WebAssembly, JSInterop wasn't ready yet so my data comes back as null. I moved all of the database calls to OnAfterRenderAsync during the first run (pre-render) and I'm basically only starting SignalR in OnInitializedAsyn.
Is this a good approach? Should I load my data from my database inside OnAfterRenderAsync during the first run (pre-render)?
Below is my new setup:
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender)
{
return;
}
try
{
TimeZoneModule = await JSRuntime.InvokeAsync("import", Cts.Token, "./timezone.js");
string timeZone = "Eastern Standard Time";
if (TimeZoneModule is not null)
{
var tzId = await TimeZoneModule.InvokeAsync(
"getBrowserTimeZone", Cts.Token);
TimeZoneInfo.TryConvertIanaIdToWindowsId(tzId, out var windowsTzId);
if (!string.IsNullOrEmpty(windowsTzId))
{
timeZone = windowsTzId;
}
}
var dotNetRef = DotNetObjectReference.Create(this);
MapModule = await JSRuntime.InvokeAsync("import", Cts.Token, "./map-module.js");
await MapModule.InvokeVoidAsync("setMapDotNetReference", Cts.Token, dotNetRef);
MapInstance = await MapModule.InvokeAsync("initMap", Cts.Token, MapElement);
await MapModule.InvokeVoidAsync("setInfoWindow", Cts.Token);
await MapModule.InvokeVoidAsync("setMapEvents", Cts.Token);
ViewModel = await MapService.InitializeMap(User.DefaultBusinessId, timeZone, Cts.Token);
MapInitialized = true;
await ApplyMapSettingsAsync();
}
catch (Exception ex)
{
Console.WriteLine($"Map initialization failed: {ex.Message}");
}
}
protected override async Task OnInitializedAsync()
{
await InitializeSignalRAsync();
}
private async Task ApplyMapSettingsAsync()
{
if (!MapInitialized || MapModule is null || MapInstance is null || ViewModel is null)
{
return;
}
if (ViewModel.BusinessMapSetting is not null)
{
await MapModule.InvokeVoidAsync("setOptions", Cts.Token, ViewModel.BusinessMapSetting);
}
if (ViewModel.Vehicles is not null)
{
await MapModule.InvokeVoidAsync("addTruckMarkers", Cts.Token, null, ViewModel.Vehicles);
}
if (ViewModel.Plants is not null)
{
await MapModule.InvokeVoidAsync("addPlantMarkers", Cts.Token, ViewModel.Plants);
}
}