[GIS] How to join a layer and a table, on-the-fly, in the ArcGIS Server JS API

arcgis-javascript-apiarcgis-onlineattribute-joins

I have a polygon feature layer and a table, both stored in ArcGIS Online. Is it possible to join them on-the-fly in the ArcGIS Server JS API?

For example, here are some sample ArcGIS Server services for:

Is it possible to join the layer and the table, and therefore to symbolize the polygons using the table's values?

Best Answer

I finally got around to answering this one. This solution uses 2 separate queries to fetch the geometry and attributes, then joins the JSON arrays to form a combined layer definition.

enter image description here

app = {};
app.map = new Map("map", {
  basemap: "gray",
  center: [-80, 38],
  zoom: 5
});
app.spatialReference = new SpatialReference({wkid:4326});

app.map.on("layers-add-result", function(results) {
  console.log("Added joined layer to map")
});

app.sfs = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,
  new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,
  new Color([255,0,0]), 2),new Color([255,255,0,0.25])
);

// Request the geometry
var geomParams = {
  where: "1=1",
  outFields: ["state_name"],
  returnGeometry: true,
  f: "json"
}

$.ajax({
  dataType: "json",
  data: geomParams,
  url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/2/query/",
  success: function (data1){
    console.log("Got geometry");
    app.data1 = data1;

    // Now request the attribute data
    var tableParams = {
      where: "1=1",
      outFields: "*",
      returnGeometry: false,
      f: "json"
    }

    $.ajax({
      dataType: "jsonp",
      jsonpCallback: "callback",
      data: tableParams,
      url: "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5/query/",
      success: function (data2){
        console.log("Got attributes")
        app.data2 = data2;

        // Join the geometry to the attributes
        $.extend( true, app.data1, app.data2 );
        console.log("Joined geometry to attributes");

        // Create a feature layer from the joined JSON
        app.featureCollection = {
          layerDefinition: {
            geometryType: app.data1.geometryType,
            spatialReference: app.spatialReference,
            objectIdField: "ObjectID",
            fields: app.data1.fields,
            drawingInfo: {
              renderer: {
                type: "simple",
                symbol: app.sfs
              }
            }
          },
          featureSet: {
            features: app.data1.features,
            geometryType: app.data1.geometryType,
            spatialReference: app.spatialReference
          }
        };
        var infoTemplate = new esri.InfoTemplate("Attributes", "${*}");  
        app.featureLayer = new FeatureLayer(app.featureCollection, {
          id: "Joined Layer",
          infoTemplate: infoTemplate
        });
        app.map.addLayers([app.featureLayer]);
      }
    });
  }
});