Select to view content in your preferred language

Use Feature Layer Attribute as GP Service Input

3113
29
Jump to solution
03-06-2017 11:15 AM
LloydBronn
Frequent Contributor

I'm trying to click on a country layer and use the country name as input for a GP tool. I've done this with XY inputs from map clicks, but I'm having a lot of trouble getting the attribute from a feature. Do I need a query task? Here is my code snippet. When I add content to the infoWindow, it displays "Country: ${NAME}" so it's not pulling that attribute from the feature layer correctly.

var country = {};

var countriesLayer = new FeatureLayer("http://<ourserver>/arcgis/rest/services/Countries_Outline/MapServer/1");
          
          map.addLayer(countriesLayer);
          
          var content = "<b>Country</b>: ${NAME}";
              
          map.on("click", function(evt){
                         
          map.graphics.clear();
          var graphic = new Graphic(evt.mapPoint);
            
          map.graphics.add(graphic);
          map.infoWindow.setFeatures([graphic]);
            
            map.infoWindow.resize(200,200);     
          map.infoWindow.setContent(content);
          map.infoWindow.show(evt.mapPoint)
            map.infoWindow.setTitle("Forecast Reports");
            
        }); 
          
            
            var today = new Date();
            var todayISO = today.toISOString().slice(0,10).replace(/-/g,"");
            
            var link = domConstruct.create("a",{
                "class": "action", 
                "id": "reportLink",
                "innerHTML": "Forecast Report", //text that appears in the popup for the link 
                "href": "javascript: void(0);"
              }, query(".actionList", map.infoWindow.domNode)[0]);
          on(link, "click", function(){
            
            domAttr.set(dom.byId("reportLink"), "innerHTML", "Generating Report...");
            
            window.gp_chart = new Geoprocessor("http://<ourserver>/arcgis/rest/services/Generate_Forecast_Report/GPServer/CreateReport");
               
               var country = window.map.infoWindow.getSelectedFeature();
                
              var taskParams = {
                "Country":country
              };
                 
              //window.gp_chart.execute(taskParams,gpChartResultAvailable,gpChartFailure);
                 window.gp_chart.execute(taskParams);
0 Kudos
29 Replies
LloydBronn
Frequent Contributor

Sorry, I'm totally confused. How do I reference the graphics array? 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

   The results object in the callback function is an array of Graphics.

featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
  //now you work with the results object which is an array of graphics
  var country = results[0].attributes["NAME"]; 
  //where 0 is the first Graphic in the results array
});
0 Kudos
LloydBronn
Frequent Contributor

Ah, Ok. Thanks! Country is still defined as a global object, though. It's not passing the value out of the callback function. 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

  So is country is a global var then just use:

featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
  //now you work with the results object which is an array of graphics
  country = results[0].attributes["NAME"]; 
  //where 0 is the first Graphic in the results array
});
0 Kudos
LloydBronn
Frequent Contributor

I tried that and put console.log(country); outside of the function. I see "Object {}" in the console. 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

 Where are you putting the console.log? If you are not doing this after the deferred is resolved then you should expect the country var to be an empty object like you are seeing.

0 Kudos
LloydBronn
Frequent Contributor

I first put it outside. Then I put it inside the click function and nothing was logged to the console. The value is not being passed to the GP tool, because I get an error that says "Cannot find 'Object{}_Forecast_Report.pdf." Shouldn't country be defined as soon as I click a feature?

Here's what my function looks like now:

var country = {};
              
          map.on("click", function(evt){
               
                var selectQuery = new Query();     
                
                selectQuery.returnGeometry = true; 
           selectQuery.geometry = geometry;
           featureLayer.selectFeatures(selectQuery,
             FeatureLayer.SELECTION_NEW, function(results){
                    country = results[0].attributes["NAME"];  
                });
               console.log(country)
               map.infoWindow.setContent(content)
        }); 
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lloyd,

  So you have the console.log outside the callback function and it looks likely that your GP call is also out side the callback so that is an issue:

var country = {};
              
          map.on("click", function(evt){
            var selectQuery = new Query();     
            selectQuery.returnGeometry = true; 
            selectQuery.geometry = geometry;
            featureLayer.selectFeatures(selectQuery,
              FeatureLayer.SELECTION_NEW, function(results){
                country = results[0].attributes["NAME"]; 
                console.log(country); //This will be good.
                //you would also want to call your GP from here as well, because
                //the country var will be populated. 
              });
              console.log(country); //this is outside the callback so it's no good.
              map.infoWindow.setContent(content)
          });
0 Kudos
LloydBronn
Frequent Contributor

OK. The problem is, once the feature is clicked, a link to the GP tool is created in the popup. I tried executing the GP tool in the callback and it's just saying "Generating Report..." forever. Nothing is happening. Is it impossible to pass a definition for a global variable from a callback function? I know I did something very similar with my other scripts.

Console.log still prints nothing when it's inside the callback. I'm not sure that country = results[0].attributes["NAME"] is actually returning anything. It also logs this error: Uncaught ReferenceError: geometry is not defined. I don't think it's even getting through the function after the  selectQuery.geometry = geometry line. I tried changing the name of the function from evt to geometry follwing the example but I got this error "Cannot read property 'wkid' of undefined"

So I went a different direction and tried an indentify task referencing the service as a dynamic layer instead of a feature layer. I'm now getting the country name from the identify task and verified it with console.log(). I tried putting the GP tool inside the initial click function, but it's not creating the link in the info window. Here is the script: 

countriesURL = "http://<ourserver>/arcgis/rest/services/Countries_Outline/MapServer"
          var countriesLayer = new ArcGISDynamicMapServiceLayer(countriesURL);
          
          map.addLayer(countriesLayer);
               
          var identifyParams;
  
          
          var identifyTask = new IdentifyTask(countriesURL);
            
               identifyParams = new IdentifyParameters();
               identifyParams.tolerance = 7;
               identifyParams.returnGeometry = true;  
               //identifyParams.layers = IdentifyParameters.LAYER_OPTION_ALL; 
               //identifyParams.layerIds = countriesLayer.visibleLayers;
               identifyParams.layerIds = [0,1,2]
               identifyParams.sr=map.spatialreference;
               identifyParams.width  = map.width; 
               identifyParams.height = map.height;
               
               
        
               

        map.on("click", function uponClick(evt){
               
            identifyParams.geometry = evt.mapPoint;
            identifyParams.mapExtent = map.extent;
            identifyTask.execute(identifyParams, function(result) { 
                for(var i = 0; i<result.length; i++){
                    country = result[i].feature.attributes["NAME"];
                } 
                    
                    console.log(country);
                    
                    var today = new Date();
                    var todayISO = today.toISOString().slice(0,10).replace(/-/g,"");
            
            
                 
                 var content = "<b>Location: </b>" + country;
               var infoTemplate = new InfoTemplate("Forecast Reports", content)
                 map.infoWindow.setContent(content);
                  map.infoWindow.show()
                  
                  var link = domConstruct.create("a",{
                "class": "action", 
                "id": "reportLink",
                "innerHTML": "Forecast Report", //text that appears in the popup for the link 
                "href": "javascript: void(0);"
              }, query(".actionList", map.infoWindow.domNode)[0]);
                    
                 
          on(link, "click", function(){
           
            domAttr.set(dom.byId("reportLink"), "innerHTML", "Generating Report...");
            
            window.gp_chart = new Geoprocessor("http://<ourserver>/arcgis/rest/services/Generate_Forecast_Report/GPServer/CreateReport");
               
               
                
              var taskParams = {
                "Country":country
              };
                 
              //window.gp_chart.execute(taskParams,gpChartResultAvailable,gpChartFailure);
                 window.gp_chart.execute(taskParams);
                 
                 function gpChartResultAvailable(results, messages){
                     domAttr.set(dom.byId("reportLink"),"innerHTML", "Forecast Report");
                     //clear any existing features displayed in the popup 
                     window.map.infoWindow.clearFeatures();
                    
                     var content = "";
                     if(results == 0){
                           var chartPath = "http://<ourserver>/PDF_Reports/" + country + "_Forecast_Report_for_" + todayISO + ".pdf";
                           content = '<IMG SRC="' + chartPath + '" width=100% height=100%/><br/><br/>';
                           content = content + '<a target="_blank" href="' + chartPath + '">Click to View or Download Chart</a>';
                     }else{
                           content = " Unable To Generate Report";
                     }
                    
                    
                     window.map.infoWindow.setContent(content);
                     window.map.infoWindow.setTitle(country);
     
               };
               
               

          function gpChartFailure(error){
            domAttr.set(dom.byId("reportLink"),"innerHTML", "Forecast Report");

            var details = domConstruct.create("div", {
              "innerHTML": "Error: " + error
            }, query(".break", window.map.infoWindow.domNode)[0],"after" );
            console.error("Error occurred: ", error);
          }

        });
                    
            });
          }
          )‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
LloydBronn
Frequent Contributor

Finally figured out a solution:

map.on("click", function uponClick(evt){
               
            identifyParams.geometry = evt.mapPoint;
            identifyParams.mapExtent = map.extent;
            identifyTask.execute(identifyParams, function(result) { 
                for(var i = 0; i<result.length; i++){
                    country = result[i].feature.attributes["NAME"];
                } 
          
               var infoTemplate = new InfoTemplate();
                  map.infoWindow.setTitle(country);
                  map.infoWindow.show(evt.mapPoint); 
                          map.getInfoWindowAnchor(evt.mapPoint));
                  
                  var link = domConstruct.create("a",{
                "class": "action", 
                "id": "reportLink",
                "innerHTML": "Generate Report",
                "href": "javascript: void(0);"
              }, query(".actionList", map.infoWindow.domNode)[0]);
                 
                 map.infoWindow.setContent(link);
0 Kudos