locationToAddress - Response to user for no candidate

2362
8
12-08-2011 10:53 AM
KeithSandell
New Contributor III
It appears that when the result of locationToAddress does not have a candidate the function simply does nothing.

The callback onLocationToAddressComplete will not fire if there is no candidate, and the absence of a candidate does not invoke an error so the errback will not fire either.

I want to tell the user there was no candidate, but I can't figure out how to fire an event if there is none.

Thoughts?

Thanks
0 Kudos
8 Replies
KellyHutchins
Esri Frequent Contributor
Keith,

The callback (onAddressToLocationsComplete) does fire when there aren't any candidates. Here's a snippet that shows one way to check for no results:

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

      function showResults(candidates) {
        if(candidates.length === 0){
          alert('no candidates');
        }
        }
0 Kudos
KeithSandell
New Contributor III
Thanks Kelly, but I think we got our wires crossed here.

My question was relating to:

reverse geocoding "onLocationToAddressComplete"

versus

geocoding "onAddressToLocationsCompelete"

The response generated by a successful reverse geocode contains the following:

dojo.io.script.jsonp_dojoIoScript2._jsonpCallback({"address":{"Street":"824 E GULF BEACH DR","City":"EASTPOINT","State":"FL","ZIP":"32328","County":null,"Loc_name":"par32300"},"location":{"x":-9444609.7624153104,"y":3461207.3870331091,"spatialReference":{"wkid":102100}}});

The response generated by an unsuccessful reverse geocode contains the following:

dojo.io.script.jsonp_dojoIoScript3._jsonpCallback();

###How can I check for the empty json in the response?###

I've tried extending your reverse geocode example, but I can't get the callback function [dojo.connect(locator, "onLocationToAddressComplete", function(candidate) {] to fire when the response is empty.

Thanks
0 Kudos
KeithSandell
New Contributor III
Guess I found a solution, unless you have something better Kelly.

I set a variable to capture the candidate and set a timer to check to see if the variable has been set.

The timer is set to 500ms, and if the variable has not been set to a candidate by the onLocationToAddressComplete event, then it executes some code to create the infoWindow at the original evt.mapPoint of the click and notify the user that there is was no address found.

Kinda of hinky since it relies on the timing of events and not cooperation, but it works.
0 Kudos
KellyHutchins
Esri Frequent Contributor
Sorry about the geocode/reversegeocode confusion. Here's a snippet that shows how to determine if no address is found when performing a reverse geocode:

        dojo.connect(map, "onClick", function(evt) {
          map.graphics.clear();
          var def = locator.locationToAddress(esri.geometry.webMercatorToGeographic(evt.mapPoint), 100);
          def.then(function(candidate){
   
            if (candidate.address) {
              //this service returns geocoding results in geographic - convert to web mercator to display on map
              var location = esri.geometry.geographicToWebMercator(candidate.location);
              var graphic = new esri.Graphic(location, symbol, candidate.address, infoTemplate);
              map.graphics.add(graphic);
              
              map.infoWindow.setTitle(graphic.getTitle());
              map.infoWindow.setContent(graphic.getContent());
              
              //display the info window with the address information
              var screenPnt = map.toScreen(location);
              map.infoWindow.resize(200,100);
              map.infoWindow.show(screenPnt,map.getInfoWindowAnchor(screenPnt));
            }
            else{
              //no address found
              console.log("No address found for this location");
            }
          });
        });

0 Kudos
KeithSandell
New Contributor III
Thanks Kelly.

Is the "then" promise integral to this solution?

I tried previously to extend the existing callback function to include an "else" statement (not using then), but nothing took place.

I took your sample and dropped in the replacement code and removed the callback function. The app works as normal, but nothing is being written to the console when the response is empty.

I attached the modified sample code, when you have a moment (as if right 🙂 ) can you please test it on your end and see if it works as expected, i.e. writes to the console.

I tried in FF and Chrome, but got nothin'.

Thanks
0 Kudos
KellyHutchins
Esri Frequent Contributor
Keith,

In my testing it looks like some locators return an error. For example if I test with the locator you are using:
http://tasks.arcgisonline.com/ArcGIS/rest/services/Locators/TA_Address_NA_10/GeocodeServer

Then an error is thrown when no addresses are matched. You can catch this using the following code:


        dojo.connect(map, "onClick", function(evt) {
          map.graphics.clear();
          var def = locator.locationToAddress(esri.geometry.webMercatorToGeographic(evt.mapPoint), 100);
    
          def.then(function(candidate){
   
            if (candidate.address) {
              //this service returns geocoding results in geographic - convert to web mercator to display on map
              var location = esri.geometry.geographicToWebMercator(candidate.location);
              var graphic = new esri.Graphic(location, symbol, candidate.address, infoTemplate);
              map.graphics.add(graphic);
              
              map.infoWindow.setTitle(graphic.getTitle());
              map.infoWindow.setContent(graphic.getContent());
              
              //display the info window with the address information
              var screenPnt = map.toScreen(location);
              map.infoWindow.resize(200,100);
              map.infoWindow.show(screenPnt,map.getInfoWindowAnchor(screenPnt));
            }
            else{
              //no address found
              console.log("No address found for this location");
            }
          }, function(error){
            console.log("error: " + error.message);
          });
        });


However if you use this locator:

http://tasks.arcgis.com/ArcGIS/rest/services/WorldLocator/GeocodeServer"

Then the code I posted earlier should work. Let me know if this is not the case in your testing .
0 Kudos
KeithSandell
New Contributor III
Thanks Kelly,

I think the error handling version will work for me.
0 Kudos
KeithSandell
New Contributor III
Well it appears that I was wrong.

I tried both solutions with my service (internal to my secure network) and the primary error that I receive appears to be generated by the application/api:

####
From the solution that does "not" catch the error:

dojo.io.script error
Error: timeout exceeded
(function(){var _1=null;if((_1||(typeo...etTimeout(dojo._loadInit,100);}})();

----

From the solution that "does" catch the error:

dojo.io.script error
Error: timeout exceeded
[Break On This Error] (function(){var _1=null;if((_1||(typeo...etTimeout(dojo._loadInit,100);}})();

error: timeout exceeded
####

The error handling method "did" work with this locator:

http://tasks.arcgisonline.com/ArcGIS/rest/services/Locators/TA_Address_NA_10/GeocodeServer

So I know the logic is sound on my end, but from the perspective of the application it is not receiving an error from "my" service.

I tested my REST endpoint with parameters and the service immediately returns, "Unable to find address for the specified location" for a location I know has no address (ocean). This is effectively what I want to filter through to the application...or at least want to be able to emulate in the application.

Any more thoughts or suggestions would be greatly appreciated.
0 Kudos