Select to view content in your preferred language

How to run query/relationshipQuery on a related table

1102
4
04-15-2014 05:36 PM
DavidGolden
Emerging Contributor
Currently we are having a FeatureLayer (Grid) which refers to a table. This feature layer stores the ID which is the foreign key of the other table.
I want to fetch data from the other table using IDs from this feature layer. Does anybody know how to use Query/RelationshipQuery to fetch data and present it in the infowindow of the Map ?

here is what i have :
var Grid = new FeatureLayer("http://gisdev2.dickinson.edu/arcgis/rest/services/Pasture_Data/WebMap/FeatureServer/1", {
          mode: FeatureLayer.MODE_SELECTION,
          outFields: ["GridID"]
        });
map.addLayers([Grid]);
        //map.addLayers([RandomPointFL]);

        function initSelectToolbar(evt) {
          var Grid = evt.layers[0].layer;
          var selectQuery = new Query();

 map.on("click", function(evt) {
            selectQuery.geometry = evt.mapPoint;
            selectQuery.objectIds = [features[0].attributes.OBJECTID];
            var relatedQuery = new RelationshipQuery();
            relatedQuery.outFields = ["GridID"];
            relatedQuery.relationshipId = 4;


            selectQuery.outFields = ["GridID"];
            var content;
            Grid.queryFeatures(selectQuery,  function(features) {
              if (features.length >= 0) {
               //store the current feature
                //graphicAttributes = evt.graphic.attributes;
                //title = graphicAttributes.req_type;

                content = "<b>GridID: </b>" + features;
                updateFeature = features[0];
                map.infoWindow.setTitle(features[0].getLayer(1).name);
                map.infoWindow.setContent(content);
                map.infoWindow.show(evt.screenPoint,map.getInfoWindowAnchor(evt.screenPoint));
                console.log(features[0]);
              } else {
                map.infoWindow.hide();
              }
            });
          });
0 Kudos
4 Replies
williamcarr
Frequent Contributor
Hi David,

I've been on the same issue with support for almost a month. This is about as far as we got. It will pull records(can be seen in the console) but getting it into an info window is perplexing us both. If you get any luck on your end could you post it.

 function findRelatedRecords(features) {
        var relatedTopsQuery = new esri.tasks.RelationshipQuery();
        relatedTopsQuery.outFields = ["*"];
        relatedTopsQuery.relationshipId = 0;
        relatedTopsQuery.objectIds = [features[0].attributes.OBJECTID];
        
        wellFeatureLayer.queryRelatedFeatures(relatedTopsQuery, function(relatedRecords) {
          console.log("related recs: ", relatedRecords);
          if ( ! relatedRecords.hasOwnProperty(features[0].attributes.OBJECTID) ) {
            console.log("No related records for ObjectID: ", features[0].attributes.OBJECTID);
            return;
          }
          
          alert("Account Number: " + relatedRecords[features[0].attributes.OBJECTID].features[0].attributes.ACCTNUM);
          alert("Address: " + relatedRecords[features[0].attributes.OBJECTID].features[0].attributes.ADDR1);
          alert("City & State: " + relatedRecords[features[0].attributes.OBJECTID].features[0].attributes.CITYSTATE);
          alert("Phone Number: " + relatedRecords[features[0].attributes.OBJECTID].features[0].attributes.PHONE);
          
          console.log(relatedRecords[features[0].attributes.OBJECTID].features[0].attributes.ACCTNUM);
          console.log(relatedRecords[features[0].attributes.OBJECTID].features[0].attributes.ADDR1);
          console.log(relatedRecords[features[0].attributes.OBJECTID].features[0].attributes.CITYSTATE);
          console.log(relatedRecords[features[0].attributes.OBJECTID].features[0].attributes.PHONE);
0 Kudos
williamcarr
Frequent Contributor
Update:

Thanks to Noah we were able to get the related table into an info window .

Query
 function findRelatedRecords(features) {
        var relatedTopsQuery = new esri.tasks.RelationshipQuery();
        relatedTopsQuery.outFields = ["*"];
        //relatedTopsQuery.relationshipId = 3;
        relatedTopsQuery.relationshipId = 0;
        //relatedTopsQuery.objectIds = [features[0].attributes.OBJECTID];
        relatedTopsQuery.objectIds = [features[0].attributes.OBJECTID];
        wellFeatureLayer.queryRelatedFeatures(relatedTopsQuery, function(relatedRecords) {
          console.log("related recs: ", relatedRecords);
          if ( ! relatedRecords.hasOwnProperty(features[0].attributes.OBJECTID) ) {
            console.log("No related records for ObjectID_1: ", features[0].attributes.OBJECTID_1);
            return;
          }
          var fset = relatedRecords[features[0].attributes.OBJECTID];
          //var fset = relatedRecords[features[0].attributes.OBJECTID];
          items = dojo.map(fset.features, function(feature) {
            return feature.attributes;
          });
          
           var data = {
            identifier: "OBJECTID",  //This field needs to have unique values
            label: "OBJECTID", //Name field for display. Not pertinent to a grid but may be used elsewhere.
            items: items
          };


Function to pull info

function getTextContent(graphic){
        return "<b>" + "OBJECTID: " + items[0].ESRI_OID + "</b><br/>" + "First Name: " + items[0].CUSTNAME + "</b><br/>" + "Address: " + items[0].ADDR1;
      }



Template
var template = new esri.InfoTemplate();
        template.setTitle("Billing");
        
        template.setContent(getTextContent);


This only pulls designated fields, but it is an acceptable workaround for me...
0 Kudos
DavidGolden
Emerging Contributor
Thanks Bill- you have been very helpful. I am getting close to it but the app still does not function. Can you explain to me what is your relatedRecords parameter in the findRelatedRecords method ? I assume it is the result of the RelationshipQuery being executed but when I plug your code in my app and change it, I see that the relatedRecords is an Object (not array) so I dont know how to take out the fields I want.

Also, what if the identifier in the data is only unique in the origin table but not the related table, can I still fetch the data ? If yes, can you tell me how to do it ?
Thanks a lot.

Update:

Thanks to Noah we were able to get the related table into an info window .

Query
 function findRelatedRecords(features) {
        var relatedTopsQuery = new esri.tasks.RelationshipQuery();
        relatedTopsQuery.outFields = ["*"];
        //relatedTopsQuery.relationshipId = 3;
        relatedTopsQuery.relationshipId = 0;
        //relatedTopsQuery.objectIds = [features[0].attributes.OBJECTID];
        relatedTopsQuery.objectIds = [features[0].attributes.OBJECTID];
        wellFeatureLayer.queryRelatedFeatures(relatedTopsQuery, function(relatedRecords) {
          console.log("related recs: ", relatedRecords);
          if ( ! relatedRecords.hasOwnProperty(features[0].attributes.OBJECTID) ) {
            console.log("No related records for ObjectID_1: ", features[0].attributes.OBJECTID_1);
            return;
          }
          var fset = relatedRecords[features[0].attributes.OBJECTID];
          //var fset = relatedRecords[features[0].attributes.OBJECTID];
          items = dojo.map(fset.features, function(feature) {
            return feature.attributes;
          });
          
           var data = {
            identifier: "OBJECTID",  //This field needs to have unique values
            label: "OBJECTID", //Name field for display. Not pertinent to a grid but may be used elsewhere.
            items: items
          };


Function to pull info

function getTextContent(graphic){
        return "<b>" + "OBJECTID: " + items[0].ESRI_OID + "</b><br/>" + "First Name: " + items[0].CUSTNAME + "</b><br/>" + "Address: " + items[0].ADDR1;
      }



Template
var template = new esri.InfoTemplate();
        template.setTitle("Billing");
        
        template.setContent(getTextContent);


This only pulls designated fields, but it is an acceptable workaround for me...
0 Kudos
williamcarr
Frequent Contributor
Crap, I think I might have left out some parts. Here is the full code(service omitted).

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>Popup</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/dojo/dijit/themes/claro/claro.css"/>
    <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css"/>
    <style>
      html,body,#map{
        padding:0;
        margin:0;
        height:100%;
      }


    </style>

    <script src="http://js.arcgis.com/3.8/"></script>
    <script>
      require([
        "esri/map",
        "esri/dijit/Popup",
        "esri/dijit/PopupTemplate",
        "esri/layers/FeatureLayer",
        "esri/symbols/SimpleMarkerSymbol",
        "esri/layers/ArcGISDynamicMapServiceLayer",
        "esri/tasks/query", "esri/tasks/QueryTask",
        "dojo/dom-class",
        "dojo/dom-construct",
        "dijit/layout/ContentPane",
        "dojo/on",
        "dojox/charting/Chart",
        "dojox/charting/themes/Dollar",
        "dojo/domReady!"
      ], function(
        Map,
        Popup,
        PopupTemplate,
        FeatureLayer,
  SimpleMarkerSymbol,
        Dynamic,
        Query,QueryTask,
        domClass,
        domConstruct,
        ContentPane,
        on,
        Chart,
        theme
      ){

        //The popup is the default info window so you only need to create the popup and 
        //assign it to the map if you want to change default properties. Here we are 
        //noting that the specified title content should display in the header bar
        var popup = Popup({
            titleInBody: false
        },domConstruct.create("div"));

        var map = new Map("map", {
          basemap: "satellite",
          center: [-88.595, 38.937],
          zoom: 11,
          infoWindow: popup
        });
        
      
               

        //define the popup content using a popup template
        //a custom chart theme (dollar) is specified. Note that you'll have to load 
        //then theme first 
        var template = new esri.InfoTemplate();
        template.setTitle("Billing");
        //template.setContent("hello");
        template.setContent(getTextContent);
         
          
         var imageParams = new esri.layers.ImageParameters();
        imageParams.layerIds = [0,1];
        imageParams.layerOption = esri.layers.ImageParameters.LAYER_OPTION_SHOW;
        var dynamicMapServiceLayer = new esri.layers.ArcGISDynamicMapServiceLayer("Secure service", {imageParameters:imageParams});
        map.addLayer(dynamicMapServiceLayer);
 
        var selectionSymbol = new esri.symbol.SimpleMarkerSymbol().setColor("red");
        wellFeatureLayer = new esri.layers.FeatureLayer("Secure service", {
          mode: esri.layers.FeatureLayer.MODE_SELECTION,
          //infoTemplate: new esri.InfoTemplate("Well Well: ${OBJECTID_1}","${OBJECTID_1}")
          infoTemplate: template
        });
        
        map.addLayers([dynamicMapServiceLayer]);
        dojo.connect(wellFeatureLayer, "onSelectionComplete", findRelatedRecords);
        map.addLayer(wellFeatureLayer);
 
        dojo.connect(map, "onClick", findWells);

        dojo.addClass(map.infoWindow.domNode, "myTheme");
        
       

   function getTextContent(graphic){
        return "<b>" + "OBJECTID: " + items[0].ESRI_OID + "</b><br/>" + "First Name: " + items[0].CUSTNAME + "</b><br/>" + "Address: " + items[0].ADDR1;
      }

   function findRelatedRecords(features) {
        var relatedTopsQuery = new esri.tasks.RelationshipQuery();
        relatedTopsQuery.outFields = ["*"];
        //relatedTopsQuery.relationshipId = 3;
        relatedTopsQuery.relationshipId = 0;
        //relatedTopsQuery.objectIds = [features[0].attributes.OBJECTID];
        relatedTopsQuery.objectIds = [features[0].attributes.OBJECTID];
        wellFeatureLayer.queryRelatedFeatures(relatedTopsQuery, function(relatedRecords) {
          console.log("related recs: ", relatedRecords);
          if ( ! relatedRecords.hasOwnProperty(features[0].attributes.OBJECTID) ) {
            console.log("No related records for ObjectID_1: ", features[0].attributes.OBJECTID_1);
            return;
          }
          var fset = relatedRecords[features[0].attributes.OBJECTID];
          //var fset = relatedRecords[features[0].attributes.OBJECTID];
          items = dojo.map(fset.features, function(feature) {
            return feature.attributes;
          });
          
           var data = {
            identifier: "OBJECTID",  //This field needs to have unique values
            label: "OBJECTID", //Name field for display. Not pertinent to a grid but may be used elsewhere.
            items: items
          };
 
        });
       
      }
 
      function findWells(evt) {

        var selectionQuery = new esri.tasks.Query();
        var tol = map.extent.getWidth()/map.width * 5;
        var x = evt.mapPoint.x;
        var y = evt.mapPoint.y;
        var queryExtent = new esri.geometry.Extent(x-tol,y-tol,x+tol,y+tol,evt.mapPoint.spatialReference);
        selectionQuery.geometry = queryExtent;
        wellFeatureLayer.selectFeatures(selectionQuery,esri.layers.FeatureLayer.SELECTION_NEW);
      }
      ;
      })
 ;
    </script>
  </head>
  
  <body class="claro">
   
   
   
   
    <div id="map"></div>
  </body>

</html>
0 Kudos