Accessing coordinates of Search point outside results function in Javascript

1655
6
Jump to solution
02-02-2017 07:30 AM
KenGalluccio
New Contributor III

I am a beginner to ESRI javascript. I am attempting to write a script that will allow the user to enter a origin and destination address, display the points, and zoom to the extent of the two points. Using the search function I have been able to geocode both points and display them on the map. I would like to get the coordinates of each point and use them to set the extent of the map. Problem I am having is that I cannot access the coordinates of the points outside fromSearch.on('select-result', function(result). I set a global variable for the coordinates.
I can assign and get the coordinates within fromSearch.on('select-result', function(result), but if I try to access this variable outside this function I get Undefined. I cannot figure out what I am missing.

ready(function () {
  // Parse DOM nodes decorated with the data-dojo-type attribute
  parser.parse();
  /*
  * Step: Specify the initial extent
  * Note: Exact coordinates may vary slightly from snippet/solution
  */
  var extentInitial = new Extent({
    "xmin" : -74.0249340000041,
    "ymin" : 42.5025420000134,
    "xmax" : -73.5927189999818,
    "ymax" : 43.1172190002567,
    "spatialReference" : {
      "wkid" : 4326
    }
  });
  // Create the map
  mapMain = new Map("cpCenter", {
    basemap : "osm",
    extent : extentInitial,
  });
  /*
  * Step: Add the ada layer layer to the map
  */
  var adaLayer = new FeatureLayer("http://services2.arcgis.com/A3lMfLhXIUtyxP6p/arcgis/rest/services/ADA_Aug14/FeatureServer/0",{
    opacity : .5
  });
  mapMain.addLayer(adaLayer);
  var symbol = new SimpleFillSymbol().setColor(new Color([255,0,0,0.5]));
  var renderer = new SimpleRenderer(symbol);
  adaLayer.setRenderer(renderer);
  /*
  * Step: Add the scalebar widget to the map
  */
  var scalebar = new Scalebar({
    map: mapMain,
    // "dual" displays both miles and kilmometers
    // "english" is the default, which displays miles
    // use "metric" for kilometers
    scalebarUnit: "dual"
  });
  //from address geocoder
  var fromSearch = new Search({
    enableLabel: true,
    enableInfoWindow: false,
    autoNavigate: false,
    map: mapMain
  }, "");
  fromSearch.startup();
  //to address geocoder
  var toSearch = new Search({
    enableLabel: true,
    enableInfoWindow: false,
    autoNavigate: false,
    map: mapMain
  }, "");
  toSearch.startup();
  dijit.registry.byId("fromButton").on("click", doSearchValue);
  function doSearchValue(e) {
    var fromAddress = document.getElementById("fromAddr").value
    //alert(fromAddress);
    //highlight symbol
    fromGeocodeSymbol = new SimpleMarkerSymbol(
      SimpleMarkerSymbol.STYLE_CIRCLE,
      20,
      new SimpleLineSymbol(
        SimpleLineSymbol.STYLE_SOLID,
        new Color([85,82,82, 0.5]),
        10
      ), new Color([76,230,0, 0.9]));
    fromSearch.sources[0].highlightSymbol = fromGeocodeSymbol;
    //set the symbol for the highlighted symbol
    fromSearch.search(fromAddress);
    //get coordinates of toAddress to pass to use to create polyline for zooming to extent.
    fromSearch.on('select-result', function(result){
      fromWebCoords = webMercatorUtils.webMercatorToGeographic(result.result.feature.geometry);
      fromXCoord = fromWebCoords.x
      console.log("inside local from function " + fromXCoord);
    });
    var toAddress = document.getElementById("toAddr").value
    //alert(toAddress);
    //highlight symbol
    var toGeocodeSymbol = new SimpleMarkerSymbol(
      SimpleMarkerSymbol.STYLE_CIRCLE,
      20,
      new SimpleLineSymbol(
        SimpleLineSymbol.STYLE_SOLID,
        new Color([85,82,82, 0.5]),
        10
      ), new Color([245,29,29, 0.9]));
    toSearch.sources[0].highlightSymbol = toGeocodeSymbol;
    //set the symbol for the highlighted symbol
    //If multiple results are found, it will default and select the first.
    toSearch.search(toAddress);
    //get coordinates of toAddress to pass to use to create polyline for zooming to extent.
    toSearch.on('select-result', function(result){
      toWebCoords = webMercatorUtils.webMercatorToGeographic(result.result.feature.geometry);
      toXCoord = toWebCoords.x
      console.log("inside local from function " + toXCoord);
    });
    console.log("Outside local function " + fromXCoord);
    console.log("Outside local function " + toXCoord);
  }
});
Tags (1)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Ken,

   OK you need to differentiate between the two then:

//get coordinates of toAddress to pass to use to create polyline for zooming to extent. 
fromSearch.on('select-result', function(result){
   fromWebCoords = webMercatorUtils.webMercatorToGeographic(result.result.feature.geometry); 
   checkResults(fromWebCoords,"from");
}); 
toSearch.on('select-result', function(result){
  toWebCoords = webMercatorUtils.webMercatorToGeographic(result.result.feature.geometry);
  checkResults(toWebCoords, "to");
});

function checkResults(geoResults, who){
  if(who === "from"){
    fromXCoord = geoResults.x;
    fromYCoord = geoResults.y;
  }else{
    toXCoord = geoResults.x;
    toYCoord = geoResults.y;
  }
  if(fromXCoord && fromYCoord && toXCoord && toYCoord){
    console.log("In checkResults from " + fromXCoord + ", " + fromYCoord );
    console.log("In checkResults to " + toXCoord + ", " + toYCoord );
  }
};

View solution in original post

0 Kudos
6 Replies
RobertScheitlin__GISP
MVP Emeritus

Ken,

   The issue you are having is that the following lines: 

console.log("Outside local function " + fromXCoord);
console.log("Outside local function " + toXCoord);‍‍

Are being called before the select-result event is fired so they are undefined. JS Code is not synchronous so it does not wait for the previous line to complete before it go to the next line. If you would have the

toSearch.on('select-result', function(result){ 

call another function that consoles the fromXCoord var you should find that it is no longer undefined.

0 Kudos
KenGalluccio
New Contributor III

Thank You for the quick reply.

I tried your suggestions and called another function from the 

toSearch.on('select-result', function(result){

and it will show the coordinate the first run through after the user clicks the Go button.

The problem I am still having is that in order to zoom to the extent of both points I need the coordinates of both points outside each of the fromSearch.on and toSearch.on functions.

When the user hits the Go button, since JS Code is not synchronous, these are always undefined outside these functions, the first time the app is run.

If the user clicks Go a second time then I am able to get the coordinates.

I am unable to determine how to access this information outside these functions when the user clicks Go initially.

Is there a way to access the geometry information of the geocoded points without using the .on event?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Ken,

   The simplest way would be to use the "select-result" on both dijits to call the same function and check if the fromXCoord and toXCoord are not undefined:

fromSearch.on('select-result', checkResults);
toSearch.on('select-result', checkResults);

function checkResults() {
  If(fromXCoord && toXCoord){
    //Now you know both are complete and you can get the values
  }
}

The other way is to use dojo/promise/all as the search dijits search method returns a promise.

0 Kudos
KenGalluccio
New Contributor III

I would still need to call function(result) to get the geometry of the points so I can assign the coordinates to fromXCoord and toXCoord, correct?

When I call the same function on both dijits it does not seem that they get called at the same time, as the results return the same coordinate for from and to.

//get coordinates of toAddress to pass to use to create polyline for zooming to extent. 
 fromSearch.on('select-result', function(result){
 fromWebCoords = webMercatorUtils.webMercatorToGeographic(result.result.feature.geometry); 
 checkResults(fromWebCoords)
 }); 
 toSearch.on('select-result', function(result){
 toWebCoords = webMercatorUtils.webMercatorToGeographic(result.result.feature.geometry);
 checkResults(toWebCoords)
 });

 function checkResults(geoResults){
 fromXCoord = geoResults.x;
 toXCoord = geoResults.x
 console.log("In checkResults from " + fromXCoord);
 console.log("In checkResults to " + toXCoord);
 };
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Ken,

   OK you need to differentiate between the two then:

//get coordinates of toAddress to pass to use to create polyline for zooming to extent. 
fromSearch.on('select-result', function(result){
   fromWebCoords = webMercatorUtils.webMercatorToGeographic(result.result.feature.geometry); 
   checkResults(fromWebCoords,"from");
}); 
toSearch.on('select-result', function(result){
  toWebCoords = webMercatorUtils.webMercatorToGeographic(result.result.feature.geometry);
  checkResults(toWebCoords, "to");
});

function checkResults(geoResults, who){
  if(who === "from"){
    fromXCoord = geoResults.x;
    fromYCoord = geoResults.y;
  }else{
    toXCoord = geoResults.x;
    toYCoord = geoResults.y;
  }
  if(fromXCoord && fromYCoord && toXCoord && toYCoord){
    console.log("In checkResults from " + fromXCoord + ", " + fromYCoord );
    console.log("In checkResults to " + toXCoord + ", " + toYCoord );
  }
};
0 Kudos
KenGalluccio
New Contributor III

That's it, thanks for all your help!