-3

I have no previous Blazor and very little asynchronous programming experience. I'm exploring using Blazor for a google maps project and trying to add a geojson point to the map using the google maps javascript api. I wasn't sure of the best way to do this, so my plan was to update the inner html of a hidden div in a blazor component and reference that value in my google map api call. When I call AddMapData (which gets a geojson string from my db) to set the html of the inner div in both OnInitializedAsync and OnAfterRenderAsync everything works great:

@page "/map"

@inject IJSRuntime JSRuntime
@using DataAccessLibrary


@inject IGeoData _db
<div id="info-box"></div>
<div hidden id="mapData">@mapData </div>

<h3>Map</h3>

<div id="map" ></div>


@code {

    private string mapData;
    private List<string> data;

    async Task<bool> AddMapData()
    {
        data = await _db.GetGeoData();
        mapData = data.First<string>();
        mapData = mapData.Substring(1, mapData.Length - 2);
        return true;
    }

    protected override async Task OnInitializedAsync()
    {
        await AddMapData();
    }

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

Why do I have to call AddMapData in both? My first thought was to only call it in the OnAfterRenderAsync override, but the div.innerhtml value is "". Any thoughts or input is appreciated.

1
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. Commented Oct 1, 2021 at 17:49

1 Answer 1

1

I fixed this by adding StateHasChanged() after AddMapData() in OnAfterRenderAsync. I no longer override OnInitializedAsync.

 protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await AddMapData();
        StateHasChanged();

        if (firstRender)
        {
            await JSRuntime.InvokeVoidAsync("initMap", null);
        }
    }
Sign up to request clarification or add additional context in comments.

2 Comments

You realize that OnAfterRenderAsync will be called each time the page re-renders. Any change to any other data will hit your DB again. Does it not work to put the AddMapData() in the OnInit and the JSRuntime call in the OnAfterRender?
@SamuelWarren I did not realize that; however, it did not work because evidently Blazor doesn't wait for OnInitializedAsync to finish before Rendering. The map would render before the data was loaded to the page and I got a jsinterop error. Thanks to your comment I found that question and implemented something similar to the top answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.