Select to view content in your preferred language

Geocoder dijit in JS API v3.3 bug? "SingleKey" vs "singleLine" search parameter name.

1338
7
Jump to solution
01-11-2013 05:47 AM
Jay_Gregory
Regular Contributor
I instantiated a geocoder in my app using the new geocoder dijit (I am very excited about this).  However, it doesn't work using my custom geocoder (ArcGIS for Server 10.1 SP1).

//geocoder digit   var geocodersArray = [{url: "http://gis.domain.com:6080/arcgis/rest/services/EON/AirportsGeocode/GeocodeServer", name:"Landing Facility Geocoder"}];   var geocoder = new esri.dijit.Geocoder({           map: map,           autoComplete: true,     maxLocations:10,      geocoders: geocodersArray,     geocoderMenu: false,     arcgisGeocoder: false         },"search");         geocoder.startup();       }


As far as I can tell (from Firebug) the request the geocoder dijit sends is:
"http://gis.domain.com:6080/arcgis/rest/services/EON/AirportsGeocode/GeocodeServer/findAddressCandida... Angeles International Airport&f=json&outSR=%7B%22wkid%22%3A102100%7D" plus a callback. 
No results are returned. 
If I run the same query directly from the REST endpoint on my server, I get
"http://gis.domain.com:6080/arcgis/rest/services/EON/AirportsGeocode/GeocodeServer/findAddressCandida... Angeles International Airport&Single+Line+Input=&outFields=&outSR=&searchExtent=&f=pjson", and results are returned. 

The difference seems to be that the geocoder dijit is using "singleLine" as the search parameter name, while ArcGIS for Server is using "SingleKey" or "Single Line Input" for the search parameter name.  I tried replacing "SingleKey" with "singleLine" in my server query, and, as expected, no results are returned.  So is this a bug in the geocoder dijit or am I missing something?

Thanks, Jay
0 Kudos
1 Solution

Accepted Solutions
KellyHutchins
Esri Frequent Contributor
Hi Jay,

This is an issue with the Geocoder widget. It currently only accepts the singleLine search parameter. Until this issue is resolved you can work around the problem using esri.setRequstPreCallback to modify the request to include your search parameter name.


      function updateLocator(ioArgs){          if(ioArgs.url === locatorUrl + "/findAddressCandidates"){             ioArgs.content['Single Line Input'] = ioArgs.content.singleLine;         }         return ioArgs;       }




See the api reference for esri.setRequestPreCallback for details:
http://help.arcgis.com/en/webapi/javascript/arcgis/jsapi/#namespace_esri/esri.setRequestPreCallback

View solution in original post

0 Kudos
7 Replies
KellyHutchins
Esri Frequent Contributor
Hi Jay,

This is an issue with the Geocoder widget. It currently only accepts the singleLine search parameter. Until this issue is resolved you can work around the problem using esri.setRequstPreCallback to modify the request to include your search parameter name.


      function updateLocator(ioArgs){          if(ioArgs.url === locatorUrl + "/findAddressCandidates"){             ioArgs.content['Single Line Input'] = ioArgs.content.singleLine;         }         return ioArgs;       }




See the api reference for esri.setRequestPreCallback for details:
http://help.arcgis.com/en/webapi/javascript/arcgis/jsapi/#namespace_esri/esri.setRequestPreCallback
0 Kudos
KevinMacLeod1
Occasional Contributor III
Is it decided that this issue will indeed be fixed, so the geocoder dijit can use custom address search fields?

If not I can look in to this workaround, but we can wait if this is a fix that is planned.

Thanks!
0 Kudos
KellyHutchins
Esri Frequent Contributor
This issue will most likely be fixed in the next release (version 3.4) so you may want to incorporate the workaround into your application until the next version is relased.
0 Kudos
Jay_Gregory
Regular Contributor
Thanks Kelly!  Your workaround worked like a charm.
0 Kudos
KevinMacLeod1
Occasional Contributor III
If my address search field is Street and the locator URL is http://sagisservices.thempc.org/saint/rest/services/Locators/SAGIS.CENTERLINES/GeocodeServer would the code be the following, below?

    function updateLocator(ioArgs){

        if(ioArgs.url === "http://sagisservices.thempc.org/saint/rest/services/Locators/SAGIS.CENTERLINES/GeocodeServer" + "/findAddressCandidates"){
            ioArgs.content['Street'] = ioArgs.content.singleLine;
    }
    return ioArgs;
}   
    


Where do we put this, after the new esri.dijit.Geocoder? After geocoder.startup()?

I tried it in a few places and still got the following outgoing JSON request   http://sagisservices.thempc.org/saint/rest/services/Locators/SAGIS.CENTERLINES/GeocodeServer/findAdd...

However, of course when I modified it by hand to put Street in, I got the right return. Without it, I got the standard JSON 400 error "Street or Intersection required". Is the code above right, and where shall I place it?

Thank you all!
0 Kudos
KevinMacLeod1
Occasional Contributor III
With the help of great ESRI customer support we solved this.

For my example, here is the code:


 geocoder.startup();
    esri.setRequestPreCallback(updateLocator);

    dojo.connect(geocoder, "onFindResults", function (results) {
        dojo.some(results.results, function (result) {
            //display a popup for the first result 
            map.infoWindow.setTitle(i18n.tools.search.title);
            map.infoWindow.setContent(result.name);
            map.infoWindow.show(result.feature.geometry);
            return true;

        });
    });
    dojo.connect(geocoder, "onClear", function () {
        if (map.infoWindow.isShowing) {
            map.infoWindow.hide();
        }
    });
}


function updateLocator(ioArgs) {

    if (ioArgs.url === "http://sagisservices.thempc.org/saint/rest/services/Locators/SAGIS.CENTERLINES/GeocodeServer" + "/findAddressCandidates") {
       
        ioArgs.content['Street'] = ioArgs.content.singleLine;

    }
    return ioArgs;
}




This works as above, like a charm!
0 Kudos
derekswingley1
Frequent Contributor II
We fixed this issue at 3.4 and this workaround is no longer necessary. When using a your own geocoding service, you can specify the name of the input field using singleLineFieldName, for instance:

var gc = [{
  url: "http://sagisservices.thempc.org/saint/rest/services/Locators/SAGIS.CENTERLINES/GeocodeServer",
  name:"Custom Geocoder",
  singleLineFieldName: "Single Line Input"
}];


Here's a complete example of using a geocode service with an input field that is not singleLine (search for 123 main st): 

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Geocoder Widget</title>
    <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.4/js/esri/css/esri.css">
    <style>
      html, body, #map {
        height:100%;
        width:100%;
        margin:0;
        padding:0;
      }
      body {
        background-color:#FFF;
        overflow:hidden;
        font-family:"Trebuchet MS";
      }
      #search {
        display: block;
        position: absolute;
        z-index: 2;
        top: 20px;
        left: 75px;
      } 
    </style>

    <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.4/"></script>
    <script>
      dojo.require("esri.map");
      dojo.require("esri.dijit.Geocoder");
      var geocoder;
      function init() {
        var map = new esri.Map("map",{
          basemap: "topo",
          center: [-117.19,34.05], //long, lat
          zoom: 13
        });

        var gc = [{
          url: "http://sagisservices.thempc.org/saint/rest/services/Locators/SAGIS.CENTERLINES/GeocodeServer",
          name:"Custom Geocoder",
          singleLineFieldName: "Single Line Input"
        }];
        var geocoder = new esri.dijit.Geocoder({
          map: map,
          autoComplete: true,
          maxLocations:10, 
          geocoders: gc,
          geocoderMenu: false,
          arcgisGeocoder: false
        }, "search");
        geocoder.startup();
      }
      dojo.ready(init);
    </script>
  </head>
  <body>
    <div id="search"></div>
    <div id="map"></div>
  </body>
</html> 
0 Kudos