Select to view content in your preferred language

Switch statement JS

6362
32
Jump to solution
05-27-2014 10:34 AM
AlexGole1
Emerging Contributor
Hi all,
I am trying to create a GIS data portal that allows users to select one out three diffent methods for data extraction.
1) extract by graphic extent
2) extract by extent of a county
3) extract by unit (calfire)

Here is my problem. I am using a switch statement that allow the users to select either one of these methods independently as shown on this thread.

However, when I trigger the either one of the cases within my function by pushing on a download button. It seems like the GPtool cant access any input data for some reasons.

errors I get for each of the functions described above :
TypeError: Unable to get property 'geometry' of undefined or null reference  TypeError: Unable to get property 'style' of undefined or null reference  TypeError: Unable to get property 'style' of undefined or null reference


My code:
var extractMethod = "extractByPoly";    var extractMethod = "extractByCounty";    var extractMethod = "extractByUnit";        function myFunction() {     //var extractMethod = "extractByPoly";     //var extractMethod = "extractByCounty";     //var extractMethod = "extractByUnit";      switch (extractMethod) {         default:              //function extractData() {             //get clip layers             var clipLayers = [];             if (registry.byId("layer1").get("checked")) {                 clipLayers.push("SRA");             }             if (registry.byId("layer2").get("checked")) {                 clipLayers.push("Burn");             }             if (clipLayers.length === 0 || map.graphics.graphics.length === 0) {                 alert("Select layers to extract and draw an area of interest.");                 return;             }              var featureSet = new FeatureSet();             var features = [];             features.push(map.graphics.graphics[0]);             featureSet.features = features;              var params3 = {                 "Layers_to_Clip": clipLayers,                 "Area_of_Interest": featureSet,                 "Feature_Format": registry.byId("formatBox").get("value")             };              domStyle.set(loading2, "display", "inline-block");             gp.submitJob(params3, completeCallback, statusCallback2, function (error) {                 alert(error);                 domStyle.set(loading2, "display", "none");             });             //}             break;          case "extractByCounty":             //function executeQueryTask(county) {             var clipLayers = [];             if (registry.byId("layer1").get("checked")) {                 clipLayers.push("SRA");             }             if (registry.byId("layer2").get("checked")) {                 clipLayers.push("Burn");             }             if (clipLayers.length === 0) {                 alert("No layers to clip, please select a layer you would like to clip...");                 return;             }              var county = document.getElementById("sel_county").value             var unit = document.getElementById("sel_unit").value             var queryTask = new QueryTask("http://webgisdevint1/arcgis/rest/services/Alex_Try/Counties/MapServer/0");                                       var query = new Query();             query.returnGeometry = true;             query.outFields = ["NAME_PCASE"];             query.where = "NAME_PCASE = '" + county + "'";             query.outSpatialReference = map.spatialReference;             queryTask.execute(query, function (featureSet) {                 var AOI = featureSet.features[0].geometry;                 var graphic = new Graphic(AOI);                 var features = [];                 features.push(graphic);                 var fSet = new FeatureSet();                 fSet.features = features;                   var params = {                     "Layers_to_Clip": clipLayers,                     "Area_of_Interest": fSet,                     "Feature_Format": registry.byId("formatBox").get("value")                 };                    domStyle.set(loading, "display", "inline-block");                 gp.submitJob(params, completeCallback, statusCallback, function (error) {                     alert(error);                     domStyle.set(loading, "display", "none");                 });             });             //}             break;           case "extractByUnit":             //function executeQueryTask1(unit) {             var clipLayers = [];             if (registry.byId("layer1").get("checked")) {                 clipLayers.push("SRA");             }             if (registry.byId("layer2").get("checked")) {                 clipLayers.push("Burn");             }             if (clipLayers.length === 0) {                 alert("No layers to clip, please select a layer you would like to clip...");                 return;             }              var unit = document.getElementById("sel_unit").value             var queryTask = new QueryTask("http://webgisdevint1/arcgis/rest/services/Alex_Try/Layers/MapServer/1");                          var query = new Query();             query.returnGeometry = true;             query.outFields = ["UNITCODE"];             query.where = "UNITCODE = '" + unit + "'";             query.outSpatialReference = map.spatialReference;             queryTask.execute(query, function (featureSet) {                 var AOI = featureSet.features[0].geometry;                 var graphic = new Graphic(AOI);                 var features = [];                 features.push(graphic);                 var fSet = new FeatureSet();                 fSet.features = features;                   var params2 = {                     "Layers_to_Clip": clipLayers,                     "Area_of_Interest": fSet,                     "Feature_Format": registry.byId("formatBox").get("value")                 };                    domStyle.set(loading1, "display", "inline-block");                 gp.submitJob(params2, completeCallback, statusCallback1, function (error) {                     alert(error);                     domStyle.set(loading1, "display", "none");                 });             });             //}     } }


Any idea why I get these errors?
0 Kudos
1 Solution

Accepted Solutions
OwenEarley
Frequent Contributor
I created a cut-down version of your code here: http://jsbin.com/dimifaju

Try running this in Chrome with the developer tools open - showing the console output.

From what I can see the toolbar events are all working and your extractMethod variable is being updated.

Also, clicking on the Extract Data button calls myFunction and the extractMethod variable is available.

In switch statements I put the default as the last option. For these type of switching functions I also
normally place the actual code for a task in their own functions. This makes it easier to read and simplifies testing as you can pass test values directly into the functions.

function myFunction() {  console.log("Extract using method:", extractMethod);  switch (extractMethod) {     case "extractByCounty":    console.log("Switch result is: extractByCounty");    var county = document.getElementById("sel_county").value;    extractByCounty(county);    break;   case "extractByUnit":    console.log("Switch result is: extractByUnit");    var unit = document.getElementById("sel_unit").value;    extractByUnit(unit);    break;   default:    console.log("Switch result (default) is: ", extractMethod);         extractByPolygon();    break;  } }  function extractByPolygon(){  console.log("Run extractByPolygon code");   // code to extract by polygon }  function extractByUnit(unit){  console.log("Run extractByUnit code:", unit);  // code to extract by unit }  function extractByCounty(county){  console.log("Run extractByCounty code:", county);  // code to extract by county }
  

Now It still does not transmit the value to the query in the switch statement.

  
Not sure why this is - try a console.log (see code above) as the first line to see if it is being called. The jsbin version (http://jsbin.com/dimifaju) is working as expected in this regard.
  
Owen
www.spatialxp.com.au

View solution in original post

0 Kudos
32 Replies
JeffPace
MVP Alum
more than likely its a scope issue, but without seeing how you call "myfunction" its hard to tell
0 Kudos
AlexGole1
Emerging Contributor
more than likely its a scope issue, but without seeing how you call "myfunction" its hard to tell



CSS:
<button id="extract" data-dojo-type="dijit/form/Button" data-dojo-props="iconClass:'DownIcon', showLabel:false">
            Extract Data
            </button>


JS:
registry.byId("extract").on("click", myFunction);
0 Kudos
JeffPace
MVP Alum
ok well since its getting into the myFunction, you are calling it correctly

however it looks like the extractMethod variable is null in the function, is this a global variable?
0 Kudos
AlexGole1
Emerging Contributor
ok well since its getting into the myFunction, you are calling it correctly

however it looks like the extractMethod variable is null in the function, is this a global variable?


Yes, extractMethod is a global variable as suggested by Steve Cole in the precedent thread.
http://forums.arcgis.com/threads/110370-One-button-to-independently-trigger-functions-of-users-choic...
0 Kudos
OwenEarley
Frequent Contributor
In your code it appears that the only places that could cause the following error message:
TypeError: Unable to get property 'geometry' of undefined or null reference 

Is when you attempt to read the geometry property of the first feature in a query task result set:
var AOI = featureSet.features[0].geometry;  // Possible problem here if there are no features

Try checking that you have a result before attempting to access the geometry:
queryTask.execute(query, function (featureSet) {
    if (featureSet.features.length === 0) {
        alert("Query task did not return any features");
        return;
    } else {
        var AOI = featureSet.features[0].geometry; 
        var graphic = new Graphic(AOI);
        etc�?�
    }
});

Without being able to test the code I am guessing that the two style property errors may be related to the first issue - as the API may be attempting to render a null geometry.

Also, you are declaring the extractMethod variable 3 times. This is effectively overwriting the same variable each time.
var extractMethod = "extractByPoly";
var extractMethod = "extractByCounty";
var extractMethod = "extractByUnit";

Declare this variable once and then change the value via UI events.

Owen
www.spatialxp.com.au
0 Kudos
AlexGole1
Emerging Contributor
In your code it appears that the only places that could cause the following error message:
TypeError: Unable to get property 'geometry' of undefined or null reference 

Is when you attempt to read the geometry property of the first feature in a query task result set:
var AOI = featureSet.features[0].geometry;  // Possible problem here if there are no features

Try checking that you have a result before attempting to access the geometry:
queryTask.execute(query, function (featureSet) {
    if (featureSet.features.length === 0) {
        alert("Query task did not return any features");
        return;
    } else {
        var AOI = featureSet.features[0].geometry; 
        var graphic = new Graphic(AOI);
        etc�?�
    }
});

Without being able to test the code I am guessing that the two style property errors may be related to the first issue - as the API may be attempting to render a null geometry.

Also, you are declaring the extractMethod variable 3 times. This is effectively overwriting the same variable each time.
var extractMethod = "extractByPoly";
var extractMethod = "extractByCounty";
var extractMethod = "extractByUnit";

Declare this variable once and then change the value via UI events.

Owen
www.spatialxp.com.au


First of all, I would like to thank you Owen for your help and insight. Thanks to you I feel I made some progress. Also your web site looks great! I will it around to the CalFire team.

Now here is the error I get:
TypeError: e is null
 

The resource from this URL is not text: http://js.arcgis.com/3.9/

.cache["dojo/dom-style"]/</l.set@http://js.arcgis.com/3.9/:136 myFunction/<@http://127.0.0.1/Clipandship/Sample9.html:347 .cache["esri/tasks/Task"]/</d<._successHandler@http://js.arcgis.com/3.9/:500 .cache["esri/tasks/QueryTask"]/</d<._handler@http://js.arcgis.com/3.9/:1391 .cache["dojo/_base/lang"]/</h.hitch/<@http://js.arcgis.com/3.9/:174 .cache["esri/tasks/QueryTask"]/</d<.execute/<.load@http://js.arcgis.com/3.9/:1387 .cache["esri/request"]/</z/<@http://js.arcgis.com/3.9/:640 c@http://js.arcgis.com/3.9/:74 d@http://js.arcgis.com/3.9/:74 .cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://js.arcgis.com/3.9/:75 c@http://js.arcgis.com/3.9/:74 d@http://js.arcgis.com/3.9/:74 .cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://js.arcgis.com/3.9/:75 c@http://js.arcgis.com/3.9/:74 d@http://js.arcgis.com/3.9/:74 .cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://js.arcgis.com/3.9/:75 .cache["esri/request"]/</z/f/<@http://js.arcgis.com/3.9/:636 c@http://js.arcgis.com/3.9/:74 d@http://js.arcgis.com/3.9/:74 .cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://js.arcgis.com/3.9/:75 c@http://js.arcgis.com/3.9/:75 d@http://js.arcgis.com/3.9/:74 .cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://js.arcgis.com/3.9/:75 c@http://js.arcgis.com/3.9/:75 d@http://js.arcgis.com/3.9/:74 .cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://js.arcgis.com/3.9/:75 c@http://js.arcgis.com/3.9/:74 d@http://js.arcgis.com/3.9/:74 .cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://js.arcgis.com/3.9/:75 c@http://js.arcgis.com/3.9/:74 d@http://js.arcgis.com/3.9/:74 .cache["dojo/_base/Deferred"]/</b.Deferred/this.callback@http://js.arcgis.com/3.9/:75 .cache["dojo/_base/xhr"]/</b.xhr/<@http://js.arcgis.com/3.9/:191 .cache["dojo/Deferred"]/</k@http://js.arcgis.com/3.9/:195 .cache["dojo/Deferred"]/</r@http://js.arcgis.com/3.9/:195 .cache["dojo/Deferred"]/</f/this.resolve@http://js.arcgis.com/3.9/:197 .cache["dojo/Deferred"]/</a@http://js.arcgis.com/3.9/:196 .cache["dojo/Deferred"]/</k@http://js.arcgis.com/3.9/:196 .cache["dojo/Deferred"]/</r@http://js.arcgis.com/3.9/:195 .cache["dojo/Deferred"]/</f/this.resolve@http://js.arcgis.com/3.9/:197 .cache["dojo/Deferred"]/</a@http://js.arcgis.com/3.9/:196 .cache["dojo/Deferred"]/</k@http://js.arcgis.com/3.9/:196 .cache["dojo/Deferred"]/</r@http://js.arcgis.com/3.9/:195 .cache["dojo/Deferred"]/</f/this.resolve@http://js.arcgis.com/3.9/:197 .cache["dojo/Deferred"]/</a@http://js.arcgis.com/3.9/:196 .cache["dojo/Deferred"]/</k@http://js.arcgis.com/3.9/:196 .cache["dojo/Deferred"]/</r@http://js.arcgis.com/3.9/:195 .cache["dojo/Deferred"]/</f/this.resolve@http://js.arcgis.com/3.9/:197 m@http://js.arcgis.com/3.9/:157 f@http://js.arcgis.com/3.9/:160 



Whatever "extraction methods" I select turns out to be null. I cannot explain why.

[HTML]Declare this variable once and then change the value via UI events.[/HTML]

Also, I still have a global variable called three time that can be overwritten because I do not see any other ways to allow the users to choose any of the three methods seamlessly (without having to deal with UI events such as check boxes or drop down combobox to select each method independently).

My overall goal is to have an app that allows users to extract data in three different ways with only one button they have to click to download/extract the data and a tool bar that approximately like on the picture attached.

[ATTACH=CONFIG]34136[/ATTACH][ATTACH=CONFIG]34137[/ATTACH]

Also is it possible to call a function locate outside of the switch loop after  a querytask.on as written below?

queryTask.on("complete", addToMap)


PS: Here is my code http://jsbin.com/tifuw/1/edit

The only thing extra that I did not remove is the TOC.js
0 Kudos
SteveCole
Honored Contributor
Alex-

Now that I see your code in the JSBin, I'm hoping I can clear up the confusion about my initial approach about using the Switch statement.

First, the initial variable declaration for extractMethod should be moved way up in your code. Add it to your series of global variables immediately before your Require() line:
      var gp, map, toc, dynaLayer1, query, queryTask;
      var symbol, infoTemplate, extractMethod;
   var AOI, graphic, clipFeatureSet, clipFeature;


Once you move it, delete those three lines that you currently have.

Next, modify your selectionToolbar "draw-end" function like this:
            selectionToolbar.on("draw-end", function (e) {
               selectionToolbar.deactivate();

               var symbol3 = new SimpleFillSymbol(
                  "solid",
                  new SimpleLineSymbol("dash", new Color([255, 0, 0]), 2),
                  new Color([255, 255, 0, 0.25])
               );

               var graphic = new Graphic(e.geometry, symbol3);
               map.graphics.add(graphic);
               extractMethod = "extractByPoly";
            });


From what I can tell, you are missing event listeners for your two combo boxes (County and Unit) so you need to create them:
        registry.byId("sel_county").on("change", function () {
            extractMethod = "extractByCounty";
         });

        registry.byId("sel_unit").on("change", function () {
            extractMethod = "extractByUnit";
         });


I think this will finally set values for extractMethod such that the switch statement will then do what it's supposed to do.

Steve
0 Kudos
AlexGole1
Emerging Contributor
Alex- 

Now that I see your code in the JSBin, I'm hoping I can clear up the confusion about my initial approach about using the Switch statement. 

First, the initial variable declaration for extractMethod should be moved way up in your code. Add it to your series of global variables immediately before your Require() line: 
      var gp, map, toc, dynaLayer1, query, queryTask;
      var symbol, infoTemplate, extractMethod;
   var AOI, graphic, clipFeatureSet, clipFeature;


Once you move it, delete those three lines that you currently have. 

Next, modify your selectionToolbar "draw-end" function like this: 
            selectionToolbar.on("draw-end", function (e) {
               selectionToolbar.deactivate();

               var symbol3 = new SimpleFillSymbol(
                  "solid",
                  new SimpleLineSymbol("dash", new Color([255, 0, 0]), 2),
                  new Color([255, 255, 0, 0.25])
               );

               var graphic = new Graphic(e.geometry, symbol3);
               map.graphics.add(graphic);
               extractMethod = "extractByPoly";
            });


From what I can tell, you are missing event listeners for your two combo boxes (County and Unit) so you need to create them: 
        registry.byId("sel_county").on("change", function () {
            extractMethod = "extractByCounty";
         });

        registry.byId("sel_unit").on("change", function () {
            extractMethod = "extractByUnit";
         });


I think this will finally set values for extractMethod such that the switch statement will then do what it's supposed to do. 

Steve

Ah. so I remove the following code before the query?
var unit = document.getElementById("sel_unit").value
and replace it (outside of the switch statement) by
  registry.byId("sel_unit").on("change", function () {
            extractMethod = "extractByUnit";
         });
I did not know anything about this listenner. Thank you for your help!
0 Kudos
AlexGole1
Emerging Contributor
My extract by graphic works like a charm! However the it does not seem like it selects anything in the combobox still

var queryTask = new QueryTask("http://webgisdevint1/arcgis/rest/services/Alex_Try/Layers/MapServer/1");
            var query = new Query();
            query.returnGeometry = true;
            query.outFields = ["UNITCODE"];
            query.where = "UNITCODE = '" + extractMethod + "'";
            query.outSpatialReference = map.spatialReference;
            queryTask.execute(query, function (featureSet) {
                 if (featureSet.features.length === 0) {
                     alert("Query task did not return any features");
                 return;
                } else {
    var AOI = featureSet.features[0].geometry;
                var graphic = new Graphic(AOI, symbol);
                var features = [];
                features.push(graphic);
                var fSet = new FeatureSet();
                fSet.features = features;


                var params2 = {
                    "Layers_to_Clip": clipLayers,
                    "Area_of_Interest": fSet,
                    "Feature_Format": registry.byId("formatBox").get("value")
                };



                domStyle.set(loading1, "display", "inline-block");
                gp.submitJob(params2, completeCallback, statusCallback1, function (error) {
                    alert(error);
                    domStyle.set(loading1, "display", "none");
                });
    }
            });
            //}
   break;
0 Kudos