Search code examples
blazorazure-maps

How to invoke a javascript constructor in Blazor?


I would like to develop a Blazor component to wrap Azure Maps javascript. The first step is to display the map on the page.

Usually, with javascript, it is done this way :

let map = new atlas.Map('mapContainer', {
    view: 'Auto',
    maxZoom:22,
    zoom:4,
    center: [2.35405, 43.855103],
    style:'road',
    showLogo:false,
    showFeedbackLink:false,                        
    authOptions: {
        authType:atlas.AuthenticationType.subscriptionKey,
        subscriptionKey: <subscriptionKey>
    }
});

With Blazor, JS cannot be directly handle this way. So, I have to use JSRuntime to write this code :

mapsModule = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.js");
    
// The following is using custom c# code
MapAuthOptions authOptions = new MapAuthOptions();
authOptions.subscriptionKey = this.subscriptionKey;
authOptions.authType = AuthenticationType.subscriptionKey;
    
MapOptions options = new MapOptions();
options.authOptions = authOptions;
options.showFeedbackLink = false;
options.showLogo = false;
options.maxZoom = 22;
options.zoom = 4;
options.view = "Auto";
options.style = "road";
    
// this line crash
await mapsModule.InvokeAsync<object>("atlas.Map", "mapContainer", options);

I wonder how to call classic JS constructor. To be more precise, how to call new atlas.Map() with InvokeAsync and Blazor ?


Solution

  • I have been developing such a solution for a couple of months now. You can take a look at the implementation here and use this Nuget package.

    My decision to create a new instance of map was basically to expose a static method which would create the map. Something like that in typescript :

    public static addMap(mapId: string,
            configuration: Configuration,
            serviceOptions: azmaps.ServiceOptions,
            enabledEvents: string[],
            eventHelper: EventHelper<MapEventArgs>): void {
    ...
            const map = new azmaps.Map(mapId, serviceOptions);
    ...
    
    

    Basically I wrap the calls to the atlas library into static methods.

    After that, the calls to your scripts are quite easy using your instance of IJsRuntime :

    await JSRuntime.InvokeVoidAsync(Constants.JsConstants.Methods.Core.AddMap.ToCoreNamespace(),
                    Id,
                    Configuration.Value,
                    ServiceOptions,
                    enabledEvents,
                    DotNetObjectReference.Create(_mapEventInvokeHelper));