ArcGIS Blog

Mapping

Developers

Speed up your JavaScript development with autocasting

By Raluca Nicola

In the 4.5 release of the ArcGIS API for JavaScript, autocasting support was expanded to all renderers, symbols, and symbol layers. This means that symbols and renderers can be created programmatically without importing their modules. All you need to do is create a simple object, specify the symbol type, and set the desired properties; then the API will autocast the object to its proper class. The samples in the API documentation were updated to consistently follow this new pattern, which cleans up the lists of required modules quite nicely.

Let’s look at an example where we set a renderer with a 3D symbol, labels, and callouts on a FeatureLayer:

To achieve this prior to 4.5 we needed to import six modules for the renderer, symbol, symbol layer, label symbol, text symbol layer, and the callout. The full list of required module imports looks like this:

require([
  "esri/WebScene",
  "esri/views/SceneView",
  "esri/layers/FeatureLayer",

  "esri/renderers/SimpleRenderer",
  "esri/symbols/PointSymbol3D",
  "esri/symbols/IconSymbol3DLayer",
  "esri/symbols/LabelSymbol3D",
  "esri/symbols/TextSymbol3DLayer",
  "esri/symbols/callouts/LineCallout3D",

  "dojo/domReady!"
], function(
  WebScene, SceneView, FeatureLayer,
  SimpleRenderer, PointSymbol3D, IconSymbol3DLayer, 
  LabelSymbol3D, TextSymbol3DLayer, LineCallout3D
){
  // use modules here
});

With this new workflow, you don’t need to import modules for the renderers and the symbols. So in the example above, you only need to import the WebScene, SceneView and FeatureLayer:

require([
  "esri/WebScene",
  "esri/views/SceneView",
  "esri/layers/FeatureLayer",

  "dojo/domReady!"
], function(
  WebScene, SceneView, FeatureLayer
){
  // use modules here
});

But how do we actually define the renderer and symbol objects without the required modules? We do this by specifying their type in a JavaScript object, just like in the example below:

If you want to play with the examples yourself, here’s the code snippet for using classes and here’s the code snippet for using types. These snippets were derived from the Point styles for cities sample in the documentation.

Similarly, you can now autocast all geometries added to graphics. For example, instead of importing esri/geometry/Polyline when manually creating a line, you can skip the import and do the following:

var polylineGraphic = new Graphic({
  geometry: {
    type: "polyline", // autocasts as new Polyline()
    paths: [
      [-0.178, 51.48791, 0],
      [-0.178, 51.48791, 1000]
    ]
  },
  symbol: {
    type: "simple-line", // autocasts as SimpleLineSymbol()
    color: [226, 119, 40],
    width: 4
  }
});

The Add Graphics to SceneView and Intro to Graphics samples were updated to follow the autocasting pattern.

When specifying object types is required

For many properties, you don’t need to specify the type of object to autocast since the API already knows the expected type. For example, you don’t need to set a type property in an object representing SimpleMarkerSymbol.outline because the expected type for the outline of a simple marker (and all other symbols) is SimpleLineSymbol.

However, renderer, symbol, symbol layer, and geometry objects are usually passed as values to polymorphic properties, meaning the API doesn’t know how to autocast the object unless the type is explicitly specified. The snippet below demonstrates both scenarios in context:

layer.renderer = {
  // type must be specified since 
  // 1 of 3 renderer types could be applied here
  type: "simple",  
  symbol: {
    // the type must also be specified for symbol properties of a renderer
    // since 1 of 10 symbol types could be used
    type: "simple-marker",  
    outline: {
      // Specifying type for outlines is not necessary 
      // since `simple-line` is the only expected type
      style: "dash-dot",
      color: [ 255, 128, 45 ]
    }
  }
};

So how do you know the value of the type property for any given scenario? There are number of ways to find the required type value. You can…

  • Find the type in the documentation,
  • Use the Symbol Playground to configure the code and copy the autocastable snippet for immediate use in your app, or
  • Infer the value.

Generally, you can infer the type by removing the generic text from the desired class name and kebabifying it. For example, SimpleFillSymbol.type is simple-fill (note that symbol is removed because it is used in all related 2D symbol class names). Another example: UniqueValueRenderer.type is unique-value (there’s no need to specify renderer in the type). IconSymbol3DLayer.type is icon (the Symbol3DLayer bit is common among all symbol layers). See the comprehensive tables below to more fully understand this pattern. Once you’re familiar with it, you won’t have to look it up in the documentation!

We’d love to hear what you think of this change or any other suggestions related to coding workflows.

Happy coding!
The ArcGIS API for JavaScript team

Class type tables

Renderer class name Type
ClassBreaksRenderer class-breaks
SimpleRenderer simple
UniqueValueRenderer unique-value
PointCloudRGBRenderer point-cloud-rgb
PointCloudClassBreaksRenderer point-cloud-class-breaks
PointCloudUniqueValueRenderer point-cloud-unique-value
PointCloudStretchRenderer point-cloud-stretch
2D Symbol class name Type
PictureMarkerSymbol picture-marker
PictureFillSymbol picture-fill
SimpleFillSymbol simple-fill
SimpleLineSymbol simple-line
SimpleMarkerSymbol simple-marker
TextSymbol text
3D Symbol/symbol layer class name Type
LineCallout3D line
ExtrudeSymbol3DLayer extrude
FillSymbol3DLayer fill
IconSymbol3DLayer icon
LabelSymbol3D label-3d
LineSymbol3D line-3d
LineSymbol3DLayer line
MeshSymbol3D mesh-3d
ObjectSymbol3DLayer object
PathSymbol3DLayer path
PointSymbol3D point-3d
PolygonSymbol3D polygon-3d
TextSymbol3DLayer text
WebStyleSymbol web-style
Geometry class name Type
Multipoint multipoint
Point point
Polygon fill
Polyline polyline

Share this article