ArcGIS Maps SDK for JavaScript – Accessing API Outside Require Callback

arcgis-maps-sdk-javascript

I am trying to figure out how I can access the ArCGIS JS API from a map after the map has been rendered, outside of require (ArcGIS JS API uses Dojo). For example, so I can do stuff like add (or remove) points, and perform other operations on the map.

I can create a map as follows:

require(["esri/config", "esri/Map", "esri/views/MapView", "esri/Graphic",
      "esri/layers/GraphicsLayer"
    ], function(esriConfig, Map, MapView, Graphic, GraphicsLayer) {
      esriConfig.apiKey = "";
      const map = new Map({
        basemap: "arcgis-topographic"
      });
      const view = new MapView({
        map: map,
        center: [-81, 41],
        zoom: 9,
        container: "viewDiv"
      });
});

And I can add a point using this function:

function plotPoint(lat, long, props) {
    const popupTemplate = {
        title: "{Name}",
        content: "{Description}"
    }
    
    const attributes = {
        Name: props.name,
        Description: props.desc
    }
    
    const graphicsLayer = new GraphicsLayer();
    map.add(graphicsLayer);
    
    const point = {
        type: "point",
        longitude: long,
        latitude: lat
    };
  
    const simpleMarkerSymbol = {
        type: "simple-marker",
        color: [226, 119, 40],
        outline: {
          color: [255, 255, 255],
          width: 1
        }
    };
    
    const pointGraphic = new Graphic({
        geometry: point,
        symbol: simpleMarkerSymbol,
        attributes: attributes,
        popupTemplate: popupTemplate
    });
  
    graphicsLayer.add(pointGraphic);
}

But plotPoint needs to be within the require callback so it can access the referenced modules. I could assign it to the global window object so I could call it outside of require, but then I may run into an issue where the function is called before it's defined.

I may need to perform other operations too from other points in the code, like removing points, adding feature layers, etc. Unfortunately, this must all exist inside some legacy code, so I can't refactor the entire application.

Is there a better pattern for accessing the API outside of require?

Best Answer

One option is to pass the module variables into the function:

function plotPoint(lat, long, props, Graphic, GraphicsLayer) {
  // ... you can use "Graphic" and "GraphicsLayer" here!
}

require(["esri/config", "esri/Map", "esri/views/MapView", "esri/Graphic",
      "esri/layers/GraphicsLayer"
    ], function(esriConfig, Map, MapView, Graphic, GraphicsLayer) {
      esriConfig.apiKey = "";
      const map = new Map({
        basemap: "arcgis-topographic"
      });
      const view = new MapView({
        map: map,
        center: [-81, 41],
        zoom: 9,
        container: "viewDiv"
      });
      plotPoint(lat, long, props, Graphic, GraphicsLayer);
});

Another option is to use the new ES Modules version of the ArcGIS API for JavaScript: https://developers.arcgis.com/javascript/latest/es-modules/