Search code examples
javascriptdojoarcgisarcgis-js-api

How to access ArcGIS JavaScript API outside of require callback?


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 (like GraphicsLayer). 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?


Solution

  • I think that the easy way to achieve what you want, if I understand you correctly, is just to define modules and include it in you application.

    A simple example base on you code would be something like this,

    GraphicsManager.js

    define([
        "dojo/_base/declare",
        "esri/Graphic",
        "esri/layers/GraphicsLayer"
    ], function(declare, Graphic, GraphicsLayer){
        return declare(null, {
            plotPoint: function(lat, long, props){
                // .. here the logic
                return graphicsLayer;
            }
        });
    });
    

    main.js

    require(["esri/config", "esri/Map", "esri/views/MapView", "app/GraphicsManager"
        ], function(esriConfig, Map, MapView, GraphicsManager) {
          esriConfig.apiKey = "";
          const map = new Map({
            basemap: "arcgis-topographic",
          });
          const view = new MapView({
            map: map,
            center: [-81, 41],
            zoom: 9,
            container: "viewDiv"
          });
          // ... some logic to get the point data
          const gm = new GraphicsManager();
          map.add(gm.plotPoint(lat, long, props));
          // .. some other logic
    });
    

    There you see that the main.js is where the application start, things are set there or in others modules. You know, map, layers, widgets, etc. Then you have your other code in modules, and you use import them as required.

    dojotoolkit - intro to modules