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 OnInitializedAsync.
Is this a good approach? Should I load my data from my database inside OnAfterRenderAsync during the first run (pre-render)?
This is my new setup:
protected async override Task OnAfterRenderAsync(bool firstRender){ if (!firstRender) { return; } try { TimeZoneModule = await JSRuntime.InvokeAsync<IJSObjectReference>("import", Cts.Token, "./timezone.js"); string timeZone = "Eastern Standard Time"; if (TimeZoneModule is not null) { var tzId = await TimeZoneModule.InvokeAsync<string>("getBrowserTimeZone", Cts.Token); TimeZoneInfo.TryConvertIanaIdToWindowsId(tzId, out var windowsTzId); if (!string.IsNullOrEmpty(windowsTzId)) { timeZone = windowsTzId; } } var dotNetRef = DotNetObjectReference.Create(this); MapModule = await JSRuntime.InvokeAsync<IJSObjectReference>("import", Cts.Token, "./map-module.js"); await MapModule.InvokeVoidAsync("setMapDotNetReference", Cts.Token, dotNetRef); MapInstance = await MapModule.InvokeAsync<IJSObjectReference>("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); }}