Variables between functions

1213
10
12-01-2011 10:48 AM
MatthewBorr
New Contributor III
Hi, this may be stupidly easy, but I cannot pass a variable (geom) to another function. I defined geom globally, and it will display when I call the "innerHTML" within its own function, but when I put it in function gpit, it comes back undefined. I need to use geom to do other things within gpit, but can't seem to see it. Any ideas why I cannot do this?

var geom;

  function showResults(candidates, result) {
        var candidate;
        var symbol = new esri.symbol.SimpleMarkerSymbol();
        var infoTemplate = new esri.InfoTemplate("Location","Address: ${address}<br />Score: ${score}<br />Source locator: ${locatorName}");

        symbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE);
        symbol.setColor(new dojo.Color([153,0,51,0.75]));

        
       
        dojo.every(candidates,function(candidate, geom){
          console.log(candidate.score);
          if (candidate.score > 80) {
            console.log(candidate.location);
            var attributes = { address: candidate.address, score:candidate.score, locatorName:candidate.attributes.Loc_name };  
            var geom = candidate.location;
            var graphic = new esri.Graphic(geom, symbol, attributes, infoTemplate);
            //add a graphic to the map at the geocoded location
            map.graphics.add(graphic);
            //add a text symbol to the map listing the location of the matched address.
            var displayText = candidate.address;
            var font = new esri.symbol.Font("16pt",esri.symbol.Font.STYLE_NORMAL, esri.symbol.Font.VARIANT_NORMAL,esri.symbol.Font.WEIGHT_BOLD,"Helvetica");
           
            var textSymbol = new esri.symbol.TextSymbol(displayText,font,new dojo.Color("#666633"));
            textSymbol.setOffset(0,8);
            map.graphics.add(new esri.Graphic(geom, textSymbol));
            return false; //break out of loop after one candidate with score greater  than 80 is found.
   
          }
        });
 
        if(geom !== undefined){
          map.centerAndZoom(geom,12);
        }
   
  
      }
     function gpit(geom){
   
   dojo.byId("a").innerHTML = geom.x;
  };
0 Kudos
10 Replies
JeffPace
MVP Alum
Hi, this may be stupidly easy, but I cannot pass a variable (geom) to another function. I defined geom globally, and it will display when I call the "innerHTML" within its own function, but when I put it in function gpit, it comes back undefined. I need to use geom to do other things within gpit, but can't seem to see it. Any ideas why I cannot do this?

var geom;

  function showResults(candidates, result) {
        var candidate;
        var symbol = new esri.symbol.SimpleMarkerSymbol();
        var infoTemplate = new esri.InfoTemplate("Location","Address: ${address}<br />Score: ${score}<br />Source locator: ${locatorName}");

        symbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE);
        symbol.setColor(new dojo.Color([153,0,51,0.75]));

        
       
        dojo.every(candidates,function(candidate, geom){
          console.log(candidate.score);
          if (candidate.score > 80) {
            console.log(candidate.location);
            var attributes = { address: candidate.address, score:candidate.score, locatorName:candidate.attributes.Loc_name };  
            var geom = candidate.location;
            var graphic = new esri.Graphic(geom, symbol, attributes, infoTemplate);
            //add a graphic to the map at the geocoded location
            map.graphics.add(graphic);
            //add a text symbol to the map listing the location of the matched address.
            var displayText = candidate.address;
            var font = new esri.symbol.Font("16pt",esri.symbol.Font.STYLE_NORMAL, esri.symbol.Font.VARIANT_NORMAL,esri.symbol.Font.WEIGHT_BOLD,"Helvetica");
           
            var textSymbol = new esri.symbol.TextSymbol(displayText,font,new dojo.Color("#666633"));
            textSymbol.setOffset(0,8);
            map.graphics.add(new esri.Graphic(geom, textSymbol));
            return false; //break out of loop after one candidate with score greater  than 80 is found.
   
          }
        });
 
        if(geom !== undefined){
          map.centerAndZoom(geom,12);
        }
   
  
      }
     function gpit(geom){
   
   dojo.byId("a").innerHTML = geom.x;
  };

More than likely its a scoping issue.  I don't see where you are calling gpit, you may try dojo.hitch(this, function()) to keep in scope.
0 Kudos
derekswingley1
Frequent Contributor
Inside your dojo.every, the "var" before geom declares it as a new, local variable so your global variable named geom is never assigned a value. I think the simplest thing to do would be to remove the var inside your dojo.every but then you'll only see the x coordinate from the last candidate that is processed.
0 Kudos
MatthewBorr
New Contributor III
Thanks for the replies. I removed the var from geom, it still comes back undefined. How can I access the geom x,y coordinates outside of the function where I define geom?
0 Kudos
derekswingley1
Frequent Contributor
Tweaked version of the sample I think you're using that logs XY coordinates after zooming to the point. Notice that geom is defined in the showResults function and also referenced inside showResults: 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=7" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>Find Address</title>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.5/js/dojo/dijit/themes/claro/claro.css">
    
    <style>
      html, body { 
        height: 100%; width: 100%;
        margin: 0; padding: 0;
      } 
      #map{ 
        padding:0;
        border:solid 1px #343642;
        margin:5px 5px 5px 0px;
      }
      .roundedCorners{
        -webkit-border-radius: 4px;
        -moz-border-radius: 4px;
        border-radius: 4px;
      }
      .shadow{
         box-shadow: 4px 4px 8px #adadad;
        -webkit-box-shadow: 4px 4px 8px #adadad;
        -moz-box-shadow: 4px 4px 8px #adadad;
        -o-box-shadow: 4px 4px 8px #adadad;
      }    
      #leftPane{
        width:20%;
        border-top: solid 1px #343642;
        border-left: solid 1px #343642;
        border-bottom: solid 1px #343642;
        background-color:#DCDAC5; 
        margin:5px 0px 5px 5px;
        color: #343642;
        font:100% Georgia,"Times New Roman",Times,serif;
        letter-spacing: 0.05em;
      }
     </style>

    <script type="text/javascript"> var djConfig = { parseOnLoad: true }; </script>
    
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.5"></script>
    <script type="text/javascript">
      dojo.require("esri.map");
      dojo.require("esri.tasks.locator");
      dojo.require("dojo.number");
      dojo.require("dijit.form.Button");
      dojo.require("dijit.form.Textarea");
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.layout.ContentPane");
      
      
      var map, locator, geom;

      function init() {
        var initExtent = new esri.geometry.Extent({"xmin":-13343554,"ymin":2967656,"xmax":-7473190,"ymax":5902838,"spatialReference":{"wkid":102100}});
        map = new esri.Map("map", { extent: initExtent});
        
        var tiledMapServiceLayer = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
        map.addLayer(tiledMapServiceLayer);

        dojo.connect(map, 'onLoad', function(map) {
          //resize the map when the browser resizes
          dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
        });
        
        locator = new esri.tasks.Locator("http://tasks.arcgisonline.com/ArcGIS/rest/services/Locators/TA_Address_NA_10/GeocodeServer");
        dojo.connect(locator, "onAddressToLocationsComplete", showResults);
        map.infoWindow.resize(200,125);
      }

      function locate() {
        map.graphics.clear();
        var address = {"SingleLine":dojo.byId("address").value};
        locator.outSpatialReference= map.spatialReference;
        locator.addressToLocations(address,["Loc_name"]);
      }

      function showResults(candidates) {
        var candidate, symbol, infoTemplate, geom;
        symbol = new esri.symbol.SimpleMarkerSymbol();
        infoTemplate = new esri.InfoTemplate("Location", "Address: ${address}<br />Score: ${score}<br />Source locator: ${locatorName}");

        symbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE);
        symbol.setColor(new dojo.Color([153,0,51,0.75]));
        
        dojo.every(candidates,function(candidate){
          if (candidate.score > 80) {
            var attributes, graphic;
            geom = candidate.location;
            attributes = { address: candidate.address, score:candidate.score, locatorName:candidate.attributes.Loc_name };   
            graphic = new esri.Graphic(geom, symbol, attributes, infoTemplate);
            map.graphics.add(graphic);
            return false; //break out of loop after one candidate with score greater  than 80 is found.
          }
        });
        if(geom !== undefined){
          map.centerAndZoom(geom,12);
          console.log("xy: ", geom.x, geom.y);
        }
      }
      dojo.addOnLoad(init);
    </script>
  </head>
  <body class="claro">
    <div id="mainWindow" dojotype="dijit.layout.BorderContainer" design="sidebar" gutters="false" style="width:100%; height:100%;">
      <div id="leftPane" class="roundedCorners" dojotype="dijit.layout.ContentPane" region="left">
        Enter an input address and the application will use the sample address locator to return the location for 
        street addresses in the United States. 
        <br />
        <textarea type="text" id="address"/>380 New York St, Redlands</textArea>
        <br />
        <button dojotype="dijit.form.Button" onclick="locate()"> Locate</button> 
      </div>
      <div id="map" class="roundedCorners shadow" dojotype="dijit.layout.ContentPane" region="center">
      </div>
    </div>
  </body>
</html>
0 Kudos
MatthewBorr
New Contributor III
Thanks again,

The problem is that I want the user to access a separate function (gpit) to run a geoprocessing service (buffer) that is accessed when they click a button. The geoprocessing service will use the address xy coordinate and also time or a distance input parameter, so they must set up the parameters, then click the button to create the buffer around the address.

I can access geom xy (and show the coordinates) fine within the Showresults function, but I need to use the geom xy in the function that takes parameters and creates the buffer.

I should have been more clear about the final goals, The geom xy will be used in a separatelyaccessed function. That's why I need to use it across functions.
0 Kudos
derekswingley1
Frequent Contributor

I can access geom xy (and show the coordinates) fine within the Showresults function, but I need to use the geom xy in the function that takes parameters and creates the buffer.


This all comes down to JavaScript scope. If you want to access a variable across functions, define your variable as global or pass the variable as an argument to your function. In the example below, geom is global. Load this page, geocode an address, open your browser's JS console and type geom.x or geom.y. You should see your coordinates.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=7" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title>Find Address</title>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.5/js/dojo/dijit/themes/claro/claro.css">
    
    <style>
      html, body { 
        height: 100%; width: 100%;
        margin: 0; padding: 0;
      } 
      #map{ 
        padding:0;
        border:solid 1px #343642;
        margin:5px 5px 5px 0px;
      }
      #leftPane{
        width:20%;
        border-top: solid 1px #343642;
        border-left: solid 1px #343642;
        border-bottom: solid 1px #343642;
        background-color:#DCDAC5; 
        margin:5px 0px 5px 5px;
        color: #343642;
        font:100% Georgia,"Times New Roman",Times,serif;
        letter-spacing: 0.05em;
      }
     </style>

    <script type="text/javascript"> var djConfig = { parseOnLoad: true }; </script>
    
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.5"></script>
    <script type="text/javascript">
      dojo.require("esri.map");
      dojo.require("esri.tasks.locator");
      dojo.require("dojo.number");
      dojo.require("dijit.form.Button");
      dojo.require("dijit.form.Textarea");
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.layout.ContentPane");
      
      
      var map, locator, geom;

      function init() {
        var initExtent = new esri.geometry.Extent({"xmin":-13343554,"ymin":2967656,"xmax":-7473190,"ymax":5902838,"spatialReference":{"wkid":102100}});
        map = new esri.Map("map", { extent: initExtent});
        
        var tiledMapServiceLayer = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
        map.addLayer(tiledMapServiceLayer);

        dojo.connect(map, 'onLoad', function(map) {
          //resize the map when the browser resizes
          dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
        });
        
        locator = new esri.tasks.Locator("http://tasks.arcgisonline.com/ArcGIS/rest/services/Locators/TA_Address_NA_10/GeocodeServer");
        dojo.connect(locator, "onAddressToLocationsComplete", showResults);
        map.infoWindow.resize(200,125);
      }

      function locate() {
        map.graphics.clear();
        var address = {"SingleLine":dojo.byId("address").value};
        locator.outSpatialReference= map.spatialReference;
        locator.addressToLocations(address,["Loc_name"]);
      }

      function showResults(candidates) {
        var candidate, symbol, infoTemplate;
        symbol = new esri.symbol.SimpleMarkerSymbol();
        infoTemplate = new esri.InfoTemplate("Location", "Address: ${address}<br />Score: ${score}<br />Source locator: ${locatorName}");

        symbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE);
        symbol.setColor(new dojo.Color([153,0,51,0.75]));
        
        dojo.every(candidates,function(candidate){
          if (candidate.score > 80) {
            var attributes, graphic;
            // geom is a global variable
            geom = candidate.location;
            attributes = { address: candidate.address, score:candidate.score, locatorName:candidate.attributes.Loc_name };   
            graphic = new esri.Graphic(geom, symbol, attributes, infoTemplate);
            map.graphics.add(graphic);
            return false; //break out of loop after one candidate with score greater  than 80 is found.
          }
        });
        if(geom !== undefined){
          map.centerAndZoom(geom,12);
          console.log("xy: ", geom.x, geom.y);
        }
      }
      dojo.addOnLoad(init);
    </script>
  </head>
  <body class="claro">
    <div id="mainWindow" dojotype="dijit.layout.BorderContainer" design="sidebar" gutters="false" style="width:100%; height:100%;">
      <div id="leftPane" class="roundedCorners" dojotype="dijit.layout.ContentPane" region="left">
        Enter an input address and the application will use the sample address locator to return the location for 
        street addresses in the United States. 
        <br />
        <textarea type="text" id="address"/>380 New York St, Redlands</textArea>
        <br />
        <button dojotype="dijit.form.Button" onclick="locate()"> Locate</button> 
      </div>
      <div id="map" class="roundedCorners shadow" dojotype="dijit.layout.ContentPane" region="center">
      </div>
    </div>
  </body>
</html>
0 Kudos
MatthewBorr
New Contributor III
Forgive my denseness here, maybe it is clear, but I'm not seeing it.

If I create a global var geom outside of any function, set it to geom = candidate.location within function Showresults, the x coordinate value should be accessible from any function, right?

So I create this function:
 function gpit(geom){
  
   dojo.byId("b").innerHTML = geom.x;
  
  };


and call it with this:

<button onclick="gpit(geom);">gp it!</button>


...geom x coordinate should be displayed. But it is not. It displays as undefined and firebug gives me the "undefined" error. I know I am missing something key here, but I'm not sure what it is. If I cannot access geom xy outside of the showresults function, I cant' build a key piece of the app functionality.

Thanks again for the help.
0 Kudos
derekswingley1
Frequent Contributor
Since geom is global, you don't need to pass it to your function as an argument. You can just call your function:
gpit()


And then access geom in your function body:
function gpit(){
  dojo.byId("b").innerHTML = geom.x;
};
0 Kudos
MatthewBorr
New Contributor III
Still undefined. I must be doing something wrong somewhere. I'll do some more research on variables, I suppose.
0 Kudos