ArcGIS API for JavaScript usage instructions

The constructor

All classes in the ArcGIS API for JavaScript have a constructor, and all properties can be set by passing arguments to the constructor.

const map = new Map({
  basemap: "topo-vector"
});

const view = new MapView({
  map: map,
  container: "map-div".center: [-122.38].scale: 5
});
Copy the code

Alternatively, the properties of an object can be specified directly using setters.

const map = new Map(a);const view = new MapView();

map.basemap = "topo-vector";           // Set a property

const viewProps = {                    // Object with property data
  container: "map-div".map: map,
  scale: 5000.center: [-122.38]}; view.set(viewProps);// Use a setter
Copy the code

attribute

Getters

The get method returns the value of an attribute. This method is a shortcut because to return the value of nested attributes without get(), for example, to return the title of a Map object’s attribute basemap, an if statement is required to check whether the basemap is undefined or empty.

const basemapTitle = null;
if (map.basemap) {                     // Make sure `map.basemap` exists
  basemapTitle = map.basemap.title;
}
Copy the code

The get method does not require an if statement. If map.basemap exists, it returns the value of map.basemap.title, otherwise null.

const basemapTitle = map.get("basemap.title");
Copy the code

== note: ==

Optional chains can also be used (? .). Operations circumvent such problems, but need to consider browser compatibility.

constbasemapTitle = map? .basemap.title;Copy the code

Setters

You can set the value of the property directly.

view.center = [ -100.40 ];
view.zoom = 6;
map.basemap = "oceans";
Copy the code

When multiple attribute values need to be changed, set() can pass a JavaScript object with the attribute name and the new value.

const newViewProperties = {
  center: [-100.40].zoom: 6
};

view.set(newViewProperties);
Copy the code

Listen for property changes

Use watch() to listen for changes to the property, which takes two parameters: the property name as a string, and a callback function to be called when the property value changes. Watch () returns a WatchHandle instance. The code example listens on the basemap.title property of a Map object and calls the titleChangeCallback function whenever the basemap title changes.

const map = new Map({
  basemap: "streets-vector"
});

function titleChangeCallback (newValue, oldValue, property, object) {
  console.log("New value: ", newValue,
              "<br>Old value: ", oldValue,
              "<br>Watched property: ", property,
              "<br>Watched object: ", object);
};

const handle = map.watch('basemap.title', titleChangeCallback);
Copy the code

You can stop listening by calling the remove method on the WatchHandle object.

handle.remove();
Copy the code

== note: ==

Not all properties can be listened on, such as collections. Register an event handler that can be listened on when changes occur to a collection.

Because the featurelayer.source and graphicslayer.graphics properties are collections, use on() instead of watch() to listen for changes to these properties.

Autocasting

Autocasting uses JavaScript objects as ArcGIS API for JavaScript class types without requiring developers to explicitly import these classes.

== note: ==

Currently, Autocasting works best in non-typescript applications due to TypeScript limitations.

In the code example, you need five API classes to create a SimpleRenderer for a FeatureLayer.

require([
  "esri/Color"."esri/symbols/SimpleLineSymbol"."esri/symbols/SimpleMarkerSymbol"."esri/renderers/SimpleRenderer"."esri/layers/FeatureLayer",].(
  Color, SimpleLineSymbol, SimpleMarkerSymbol, SimpleRenderer, FeatureLayer
) = > {
  const layer = new FeatureLayer({
    url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/WorldCities/FeatureServer/0".renderer: new SimpleRenderer({
      symbol: new SimpleMarkerSymbol({
        style: "diamond".color: new Color([255.128.45]),
        outline: new SimpleLineSymbol({
          style: "dash-dot".color: new Color([0.0.0])})})})}); });Copy the code

With Autocasting, you don’t have to import renderers and symbol classes; The only modules that need to be imported are ESri/Layers /FeatureLayer.

require([ "esri/layers/FeatureLayer"].(FeatureLayer) = > {
  const layer = new FeatureLayer({
    url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/WorldCities/FeatureServer/0".renderer: {                        // autocasts as new SimpleRenderer()
      symbol: {                        // autocasts as new SimpleMarkerSymbol()
        type: "simple-marker".style: "diamond".color: [ 255.128.45].// autocasts as new Color()
        outline: {                     // autocasts as new SimpleLineSymbol()
          style: "dash-dot".color: [ 0.0.0 ]           // autocasts as new Color()}}}}); });Copy the code

To see if a class can autocast, look at the documentation for each class. If a property can be autocast, the following image will appear:

Asynchronous data

Promise

Promise is typically used with then(), which defines the callback function that is called if Resolved and the error function if rejected. The first argument is always a success callback and the second optional argument is an error callback.

someAsyncFunction().then(callback, errorCallback);
Copy the code

The catch() method can be used to specify an error callback for a Promise or chain of Promise functions.

someAsyncFunction()
  .then((resolvedVal) = > {
    console.log(resolvedVal);
  }).catch((error) = > {
    console.error(error);
  });
Copy the code

In the example, the GeometryService is used to project the geometry of several points to a new spatial reference. In the document of GeometryService.project, project() returns a Promise that resolves into an array of projected geometry.

require([
  "esri/tasks/GeometryService"."esri/tasks/support/ProjectParameters",].(GeometryService, ProjectParameters) = > {
    const geoService = new GeometryService( "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer" );
    const projectParams = new ProjectParameters({
      geometries: [points],            
      outSR: outSR,
      transformation = transformation
    });
    geoService.project(projectParams)
      .then((projectedGeoms) = > {
       console.log("projected points: ", projectedGeoms);
      }, (error) = > {
        console.error(error);
      });
});
Copy the code

Promise function chain

One of the advantages of using promises is that you can concatenate multiple promises using THEN (). When more than one Promise is chained together, the resolved value of one Promise is passed to the next Promise. This allows blocks of code to execute sequentially without having to nest callbacks between each other.

== note: ==

The callback function must use the return keyword to return a value to the next Promise.

  const bufferLayer = new GraphicsLayer();

  function bufferPoints(points) {
    return geometryEngine.geodesicBuffer(points, 1000."feet");
  }

  function addGraphicsToBufferLayer(buffers) {
    buffers.forEach((buffer) = > {
      bufferLayer.add(new Graphic(buffer));
    });
    return buffers;
  }

  function calculateArea(buffer) {
    return geometryEngine.geodesicArea(buffer, "square-feet");
  }

  function calculateAreas(buffers) {
    return buffers.map(calculateArea);
  }

  function sumArea(areas) {
    for (let i = 0, total = 0; i < areas.length; i++) {
      total += areas[i];
    }
    return total;
  }

  geoService.project(projectParams)
    .then(bufferPoints)
    .then(addGraphicsToBufferLayer)
    .then(calculateAreas)
    .then(sumArea)
    .catch((error) = > {
      console.error("One of the promises in the chain was rejected! Message:", error);
    });
Copy the code

You can also use async, await keywords, which in short are syntactic candy based on promises to make asynchronous code look more like synchronous code. Please refer to the documentation for details.

Manual loading

If the View is constructed with a Map instance, the load method automatically loads all resources referenced in the View and its associated Map. Simply put, when an instantiated layer is not referenced by a Map or view, all resources served by the layer are not automatically loaded. You need to manually call the load method to load the required resources to complete the initialization.

Load states include not-loaded, loading, failed, and loaded, indicating that the load is not loaded, loading, loading failed, and loading succeeded respectively.

The following state transitions represent the phases through which a loadable resource goes.

The load state can be verified with the following code:

require(["esri/Map"."esri/views/MapView"."esri/layers/FeatureLayer"].(Map, MapView, FeatureLayer) = > {
        const map = new Map({
            basemap: "osm"
        })
        const view = new MapView({
            map,
            container: "view"
        })
        const layer = new FeatureLayer({
            url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/0"
        });
        console.log(layer.loadStatus)
        console.log(layer.fields)
        layer.load().then(() = > {
            console.log(layer.loadStatus)
            console.log(layer.fields)
        }, (err) = > {
            console.log(err)
        })
    });
Copy the code

This is FeatureLayer, not associated with a Map or View, that prints its load state and contained field properties after instantiation, and prints its load state and contained fields again after a manual call to Load (). The browser output looks like this:

The above results can be verified.

FromJSON method

The fromJSON method creates an instance of the specified class from the JSON generated by the ArcGIS product. JSON in this format is typically created by the toJSON() method or through a query from the REST API. Cannot be mixed with regular JSON or GeoJSON.

JsonUtils helper method

Several jsonUtils classes are provided as utility classes when instantiating an object using fromJSON().

  • esri/geometry/support/jsonUtils
  • esri/renderers/support/jsonUtils
  • esri/symbols/support/jsonUtils

These classes can quickly handle situations where a JSON object is a geometry, renderer, or symbol from a REST API, but the object type is unknown. For example, when a layer of the renderer from REST requests, and not sure whether the renderer UniqueValueRenderer call esri/renderers/support/jsonUtils class to help identify the type of the renderer.

require([ "esri/renderers/support/jsonUtils"."esri/layers/FeatureLayer"].( rendererJsonUtils, FeatureLayer ) = > {

  const rendererJSON = {               // renderer object obtained via REST request
     "authoringInfo":null."type":"uniqueValue"."field1":"CLASS"."field2":null."field3":null."expression":null."fieldDelimiter":null."defaultSymbol": {"color": [235.235.235.255]."type":"esriSLS"."width":3."style":"esriSLSShortDot"
     },
     "defaultLabel":"Other major roads"."uniqueValueInfos":[
        {
           "value":"I"."symbol": {"color": [255.170.0.255]."type":"esriSLS"."width":10."style":"esriSLSSolid"
           },
           "label":"Interstate"
        },
        {
           "value":"U"."symbol": {"color": [223.115.255.255]."type":"esriSLS"."width":7."style":"esriSLSSolid"
           },
           "label":"US Highway"}};// Create a renderer object from its JSON representation
  const flRenderer = rendererJsonUtils.fromJSON(rendererJSON);

  // Set the renderer on a layer
  const layer = new FeatureLayer({
    renderer: flRenderer
  });
});
Copy the code