Search code examples
reactjsazureazure-maps

In React CRA, Azure Map external standalone scripts (azure-maps-geolocation-control.js) cannot read namespace of Azure Map SDK


RI am working with a CRA React project. In a React component, I have tried to import and load an external Azure Map standalone script like azure-maps-geolocation-control.js which adds on to the Azure Map namespace (atlas). In this React component, I have imported Azure Map SDK like azure-maps-control which works fine to render the map and supply the namespace.

Under map ready event, I have tried to instantiate GeolocationControl object but seems like the script cannot read the atlas namespace. This external script is placed in public folder and dynamically placed in of index.html .

How to make the script link to Azure Map SDK namespace, in a React component? Thank you

import React, { useEffect, useRef, useState } from 'react';
import atlas from 'azure-maps-control';     


const Map = () => {
    const mapContainerRef = useRef(null);

    useEffect(() => {
        const map = new atlas.Map(mapContainerRef.current, {
            center: [103.852, 1.290],
            zoom: 15,
            view: 'Auto',
            authOptions: {
                authType: 'subscriptionKey',
                subscriptionKey: 'my-sub-key'
            }
        })

        map.events.add('ready', async function () {
            const script = document.createElement('script');
            script.src =  `${process.env.PUBLIC_URL}/lib/azure-maps-geolocation-control.js`;
            script.type = 'text/javascript';
            script.async = true;
            document.head.appendChild(script);
            
            map.controls.add([
                new atlas.control.ZoomControl(),
                new atlas.control.CompassControl(),
                new atlas.control.PitchControl(),
                new atlas.control.GeolocationControl({
                    style: 'auto'       
                })
            ], {
                position: "top-left"
            });
        })

        return () => {
            map.dispose();
        };
    }, []);

    return (
        <>
            <div ref={mapContainerRef} style={{ height: "100%", width: "100%" }}></div>
        </>
    );
};

export default Map;

I have tried importing the Azure Map SDK (azure-maps-control) and initializing the map correctly. Then dynamically adding external Azure Map script (azure-maps-geolocation-control.js) to in index.html, under the map ready event.

Expecting the script to integrate with the SDK but it seems to not be able to read/merge with the atlas namespace in the SDK.


Solution

  • To integrate the external Azure Map script (azure-maps-geolocation-control.js) with the Azure Map SDK namespace (atlas) in a React component

    • Import the Azure Map SDK (azure-maps-control) in the React component and dynamically load the external Azure Map script (azure-maps-geolocation-control.js) after the map is ready.
    • Ensure that the external script is loaded after the Azure Map SDK so that it can access the atlas namespace and Instantiate the GeolocationControl object within the map-ready event handler.
    import React, { useEffect, useRef } from 'react';
    import atlas from 'azure-maps-control';
    
    const Map = () => {
        const mapContainerRef = useRef(null);
    
        useEffect(() => {
            const initMap = async () => {
                const map = new atlas.Map(mapContainerRef.current, {
                    center: [103.852, 1.290],
                    zoom: 15,
                    view: 'Auto',
                    authOptions: {
                        authType: 'subscriptionKey',
                        subscriptionKey: 'my-sub-key'
                    }
                });
    
                map.events.add('ready', async () => {
                    // Dynamically load the external Azure Map script
                    const script = document.createElement('script');
                    script.src = `${process.env.PUBLIC_URL}/lib/azure-maps-geolocation-control.js`;
                    script.type = 'text/javascript';
                    script.async = true;
    
                    // Ensure that the script is loaded after the Azure Map SDK
                    script.onload = () => {
                        // Instantiate the GeolocationControl object after the script is loaded
                        new atlas.control.GeolocationControl({
                            style: 'auto'
                        }).addTo(map);
                    };
    
                    document.head.appendChild(script);
                });
    
                return () => {
                    map.dispose();
                };
            };
    
            initMap();
        }, []);
    
        return (
            <div ref={mapContainerRef} style={{ height: '100vh', width: '100%' }} />
        );
    };
    
    export default Map;
    
    
    • use useEffect to initialize the map and dynamically load the external script after the map is ready and the external script is loaded asynchronously, and the onload callback ensures that the GeolocationControl object is instantiated only after the script is fully loaded.
    • The GeolocationControl object is added to the map using the addTo method provided by the Azure Map SDK.
    npm i azure-maps-control
    

    enter image description here

    enter image description here