Select to view content in your preferred language

Switch statement JS

7872
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
32 Replies
AlexGole1
Emerging Contributor
Error I get after spinning a bit

"Resuming debugger: error during debugging loop: TypeError: firstViewRangeElement is null"
0 Kudos
AlexGole1
Emerging Contributor
Error I get after spinning a bit

"Resuming debugger: error during debugging loop: TypeError: firstViewRangeElement is null"


Steve,
Jeff Pace figured out that the listener would work this way:

 
on(registry.byId("sel_unit"), "Change", function () {
            extractMethod = "extractByUnit";
            console.log("You are selecting a unit!");
         });


Now It still does not transmit the value to the query in the switch statement.
0 Kudos
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
0 Kudos
SteveCole
Honored Contributor
@Alex-  I'm glad Jeff's fresh eyes was able to figure out what I was missing.

@Owen- what you posted looks like it's doing what I was originally suggesting. I think you've got the right solution.

Steve
0 Kudos
AlexGole1
Emerging Contributor
@Alex-  I'm glad Jeff's fresh eyes was able to figure out what I was missing.

@Owen- what you posted looks like it's doing what I was originally suggesting. I think you've got the right solution.

Steve


Steve or Owen, can you explain this portion of Owen's answer please:

[HTML]Also, you are declaring the extractMethod variable 3 times. This is effectively overwriting the same variable each time.
Code:
var extractMethod = "extractByPoly";
var extractMethod = "extractByCounty";
var extractMethod = "extractByUnit";
Declare this variable once and then change the value via UI events.

Owen[/HTML]

Should I have just one variable then?  Also when Owen said "change the value via UI events." As a newbie in JS what is a UI events? As I understand it, it is a button, drop down menu or something like it that I add to the user interface? If I understood correctly. The user wont be able to change "methods" seemlessly and will have select manually from a UI event like a button, drop down? If any of you could clarify that would be a huge help. Thank you for all your help! Alex
0 Kudos
SteveCole
Honored Contributor
UI Events = User Interface events. What we're saying is that the value for the variable extractMethod should only be set as a result of an action taken by a user using your web app. The value should only be set/modified if the user

a.) draws a polygon,
b.) selects a county from the county combo box list, or
c.) selects a unit from the unit combo box list.

All three of these actions are basically UI events.

Owen states "declare this variable once" and that's what I was suggesting my moving it way up in your code to the very top, before the Require() stuff. Provided you have incorporated what Owen last posted in his jsbin example, you should DELETE the following lines that were in your original code posted:
var extractMethod = "extractByPoly";
var extractMethod = "extractByCounty";
var extractMethod = "extractByUnit";


Remember earlier in this thread when I posted this code snippet?
      var gp, map, toc, dynaLayer1, query, queryTask;
      var symbol, infoTemplate, extractMethod;
   var AOI, graphic, clipFeatureSet, clipFeature;


The variable is declared as global and ready to use (you don't necessarily need to assign a value to declare a variable).

Hope this clears up some of the confusion!

Steve
0 Kudos
AlexGole1
Emerging Contributor
UI Events = User Interface events. What we're saying is that the value for the variable extractMethod should only be set as a result of an action taken by a user using your web app. The value should only be set/modified if the user  

a.) draws a polygon, 
b.) selects a county from the county combo box list, or  
c.) selects a unit from the unit combo box list.  

All three of these actions are basically UI events. 

Owen states "declare this variable once" and that's what I was suggesting my moving it way up in your code to the very top, before the Require() stuff. Provided you have incorporated what Owen last posted in his jsbin example, you should   DELETE the following lines that were in your original code posted: 
var extractMethod = "extractByPoly";
var extractMethod = "extractByCounty";
var extractMethod = "extractByUnit";


Remember earlier in this thread when I posted this code snippet? 
      var gp, map, toc, dynaLayer1, query, queryTask;
      var symbol, infoTemplate, extractMethod;
   var AOI, graphic, clipFeatureSet, clipFeature;


The variable is declared as global and ready to use (you don't necessarily need to assign a value to declare a variable). 

Hope this clears up some of the confusion! 

Steve


Thanks Steve that clears it up! These terms are much clearer to me now!

Now, thanks to you, Owen and Jeff I have a functioning listener and the default case works like a charm. The switch case seems to overwrite the global variable value like should too! However I am still getting a null value error in my console.log

TypeError {stack: "TypeError: Cannot read property 'style' of nullâ?µ  â?¦allback (http://js.arcgis.com/3.9/init.js:75:350)", message: "Cannot read property 'style' of null"}
message: "Cannot read property 'style' of null"
stack: "TypeError: Cannot read property 'style' of nullâ?µ    at Object.l.set (http://js.arcgis.com/3.9/init.js:136:409)â?µ    at http://127.0.0.1/Clipandship/Sample13.html:339:25â?µ    at d._successHandler (http://js.arcgis.com/3.9/init.js:500:240)â?µ    at d._handler (http://js.arcgis.com/3.9/init.js:1391:359)â?µ    at http://js.arcgis.com/3.9/init.js:174:23â?µ    at Object.c.load (http://js.arcgis.com/3.9/init.js:1387:350)â?µ    at http://js.arcgis.com/3.9/init.js:640:344â?µ    at c (http://js.arcgis.com/3.9/init.js:74:221)â?µ    at d (http://js.arcgis.com/3.9/init.js:74:10)â?µ    at resolve.callback (http://js.arcgis.com/3.9/init.js:75:350)"
__proto__: Error
 "TypeError: Cannot read property 'style' of null
    at Object.l.set (http://js.arcgis.com/3.9/init.js:136:409)
    at http://127.0.0.1/Clipandship/Sample13.html:339:25
    at d._successHandler (http://js.arcgis.com/3.9/init.js:500:240)
    at d._handler (http://js.arcgis.com/3.9/init.js:1391:359)
    at http://js.arcgis.com/3.9/init.js:174:23
    at Object.c.load (http://js.arcgis.com/3.9/init.js:1387:350)
    at http://js.arcgis.com/3.9/init.js:640:344
    at c (http://js.arcgis.com/3.9/init.js:74:221)
    at d (http://js.arcgis.com/3.9/init.js:74:10)
    at resolve.callback (http://js.arcgis.com/3.9/init.js:75:350)" 





I don't understand why since the listener works fine and it seems like there is a selection made...
0 Kudos
AlexGole1
Emerging Contributor
Everything works like it is supposed to be. I applied Owen's edits above which  seems like it is the way to go.
However I cannot get rid of this error:
TypeError: e is null


As you can see on the image the query works fine, the value is fed to the feature set correctly but it still retuns an error saying "e is null"

[ATTACH=CONFIG]34316[/ATTACH]

Here is my latest and greatest jsbin example.
0 Kudos
SteveCole
Honored Contributor
Does it give you a line number when it errors? It looks like you only have one instance of an "e" variable in the "draw-complete" event handler.

A type error is an error that happens when the variable has a value that is different than what should normally be present. For example, you buy a product with assembly instructions but it only comes with instructions in Spanish. Code specific examples are passing a numeric value when something expects text, a function expects a polyline as input and you pass it a point, etc.

In this case, e should have some sort of value but for whatever reason, it is null (or empty).

First things first- make a backup of your project / HTML file before proceeding. You've gotten to a certain point so if things get screwed up, you want a recent spot to start again.

Back up? Good. Here's something to try: let's tweak your initSelectionToolbar function. First, modify the function like this:
         function initSelectionToolbar() {
            map.graphics.clear();

            selectionToolbar = new Draw(map);
            selectionToolbar.on("draw-end", addGraphic);
         }


Next, add a NEW function to your project named addGraphic:
function addGraphic(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";
            }


Most ESRI samples tend to shy away from using inline functions within event handlers and usually make a call to some other function within the project.  I'm wondering if that's the issue here...

Steve
0 Kudos
AlexGole1
Emerging Contributor
Does it give you a line number when it errors? It looks like you only have one instance of an "e" variable in the "draw-complete" event handler.

A type error is an error that happens when the variable has a value that is different than what should normally be present. For example, you buy a product with assembly instructions but it only comes with instructions in Spanish. Code specific examples are passing a numeric value when something expects text, a function expects a polyline as input and you pass it a point, etc.

In this case, e should have some sort of value but for whatever reason, it is null (or empty).

First things first- make a backup of your project / HTML file before proceeding. You've gotten to a certain point so if things get screwed up, you want a recent spot to start again.

Back up? Good. Here's something to try: let's tweak your initSelectionToolbar function. First, modify the function like this:
         function initSelectionToolbar() {
            map.graphics.clear();

            selectionToolbar = new Draw(map);
            selectionToolbar.on("draw-end", addGraphic);
         }


Next, add a NEW function to your project named addGraphic:
function addGraphic(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";
            }


Most ESRI samples tend to shy away from using inline functions within event handlers and usually make a call to some other function within the project.  I'm wondering if that's the issue here...

Steve


Thanks Steve! I tried your solution but I get the same error

TypeError: e is null       /3.9/(line205)


and then here is the NOT clear at all description of the error:

.cache["dojo/dom-style"]/</l.set@http://js.arcgis.com/3.9/:136 extractByCounty/<@http://127.0.0.1/Clipandship/Sample14.html:344 .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 


The query returns fine, the geometry returns fine as showed here:

{"displayFieldName":"NAME_PCASE","fieldAliases":{"NAME_PCASE":"NAME_PCASE"},"geometryType":"esriGeometryPolygon","spatialReference":{"wkid":102100,"latestWkid":3857},"fields":[{"name":"NAME_PCASE","type":"esriFieldTypeString","alias":"NAME_PCASE","length":40}],"features":[{"attributes":{"NAME_PCASE":"Amador"},"geometry":{"rings":[[[-13366405.54622118,4679183.5292336093],[-13366408.500613371,4676607.93449526],[-13366401.718231125,4673895.8587084692],[-13366403.702313054,4668085.3689144133],[-13366396.034404758,4668085.1344282823],[-13366400.831451345,4665497.5970672229],[-13366401.861406215,4661304.9277501674],[-13366410.580302747,4657338.6184302801],[-13366410.664397134,4652914.6460015653],[-13366412.591153229,4651707.281880768],[-13366441.5974274,4651698.5911074057],[-13366453.152847191,4651701.5166428825],[-13366466.655153036,4651692.9827292729],[-13366546.901805598,4651688.4913324062],[-13366570.057272101,4651682.8291643728],[-13366592.301112154,4651673.2883800501],[-13366608.708902633,4651671.2459100373],[-13366635.832216404,4651658.6566127045],[-13366667.727691818,4651649.4280354334],[-13366728.556206429,4651640.4763607373],[-13366745.938966284,4651641.0274053961],[-13366800.085875837,4651619.0479039568],[-13366819.4339015,4651615.1830413081],[-13366895.760241358,4651583.0119334171],[-13366925.670265833,4651573.0793578112],[-13366951.790278206,4651566.864210465],[-13366972.067358896,4651559.1690005772]


in IE11 I get this error:

TypeError: Unable to get property 'style' of undefined or null reference

I am not sure...
0 Kudos