Updating Find Task Woes

1169
18
Jump to solution
11-04-2013 07:03 AM
AlexDeVine
New Contributor III
Morning,

In my quest to update one of my web apps to AMD style, I am running into a perplexing issue with my find task. The structure of this task is found in many places in the Samples. The following code is my version of it on my app:

Global variables, require and function calls
 var map, navToolbar, infoTemplate, identifyTask, identifyParams, findTask, findParams, graphicsLayer, searchText;         require(["dojo/parser", "dojo/_base/connect", "dojo/_base/array", "esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/layers/GraphicsLayer", "esri/graphic", "esri/InfoTemplate", "esri/toolbars/navigation", "dojo/dom", "esri/tasks/FindTask",             "esri/tasks/FindParameters", "dijit/dijit", "dijit/layout/BorderContainer", "dijit/layout/ContentPane",             "dijit/layout/AccordionContainer", "dijit/form/TextBox", "dijit/form/Button", "dijit/Toolbar", "dijit/Tooltip", "dijit/registry",             "dojo/_base/Color", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol",             "esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters", "esri/tasks/IdentifyResult", "dojo/domReady!"         ], function (           parser, connect, array, Map, ArcGISDynamicMapServiceLayer, GraphicsLayer, Graphic, InfoTemplate, Navigation, dom, FindTask,           FindParameters, Color, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, IdentifyTask, IdentifyParameters, IdentifyResult, registry         )


The find task:

function execute(searchText) {             //set the search text to find parameters             //create find tasks with url to map services             findTask = new esri.tasks.FindTask("http://eagle.camplan.uga.edu:6080/arcgis/rest/services/CampusMap/UGA_CampusMap_Base/MapServer");             //create find parameters and define known values             findParams = new esri.tasks.FindParameters();                          findParams.returnGeometry = true;             //findParams.outSpatialReference = map.spatialReference;             findParams.layerIds = [7];             findParams.searchFields = ["NAME", "NUMBER"];                          findParams.searchText = searchText;              findTask.execute(findParams, showResults, findErr);          }          function showResults(results) {              //display the results of the building text search             //symbology for graphics             markerSymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE, 20, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 255, 255]), 1), new dojo.Color([0, 255, 255, 0.25]));             lineSymbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASH, new dojo.Color([0, 255, 255]), 1);             polygonSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_NONE, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASHDOT, new dojo.Color([0, 255, 255]), 2), new dojo.Color([0, 255, 255, 0.25]));              //find results return an array of graphics in the graphicslayer.             graphicsLayer = new esri.layers.GraphicsLayer();             graphicsLayer.spatialReference = map.spatialReference;             map.graphics.clear();              //Build an array of attribute information and add each found graphic to the map             dojo.forEach(results, function (result) {                 var graphic = new esri.Graphic(result.feature);                 graphic.spatialReference = map.spatialReference;                 graphic.setSymbol(polygonSymbol);                 map.graphics.add(graphic);                 graphicsLayer.add(graphic);             });              //create an extent matching the graphics of the parcel(s)             var zoomExtent = esri.graphicsExtent(graphicsLayer.graphics);             var zoomXmin = zoomExtent.xmin;             var zoomXmax = zoomExtent.xmax;             var zoomScale = zoomXmax - zoomXmin;             if (zoomExtent.xmin < 2460000 || zoomExtent.ymin < 1345000 || zoomExtent.xmax > 2630000 || zoomExtent.ymax > 1505000) {                 apprise("Your Find Building results include a building outside of ACC/Main UGA Campus. Please refine your search");             }             else if (zoomScale > 10000) {                 apprise("Your Find Building results require a coarse scale to display. Please refine your search");             }             else {                 map.setExtent(zoomExtent.expand(2));             }         }          function findErr(error) {             //Alerts the user to a return of no results in building search             apprise("Your search returned no results. Please refine your search.");         }


The find task function showResults is failing to findErr at the point when I attempt to add the graphic to the map and to the graphicsLayer:

                map.graphics.add(graphic);                 graphicsLayer.add(graphic);


If I comment out these add statements, I fail out at the extent creation, but one thing at a time, right? 🙂

Anyone have any ideas on why I cannot add the graphics to the map or to the graphics layer? I tried to address any issue that spatial reference might cause with setting the graphics returned from the FindTask and the GraphicsLayer to the map Spatial Reference, but I am at a loss.

Alex DeVine
0 Kudos
1 Solution

Accepted Solutions
AlexDeVine
New Contributor III
Figured it out.

you used to could get away with this when constructing a graphic:

graphic = new esri.Graphic(result.feature);


it appears now that you have to be more descriptive:

graphic = new esri.Graphic(result.feature.geometry);


Lesson learned.

Thank you all for allowing me to bounce ideas and all the great help.

Alex

View solution in original post

0 Kudos
18 Replies
KenBuja
MVP Esteemed Contributor
The first thing you have to do is make sure the require modules match the function aliases in the correct order


        require(["dojo/parser", "dojo/_base/connect", "dojo/_base/array", "esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/layers/GraphicsLayer", "esri/graphic", "esri/InfoTemplate", "esri/toolbars/navigation", "dojo/dom", "esri/tasks/FindTask",
            "esri/tasks/FindParameters", "dijit/dijit", "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
            "dijit/layout/AccordionContainer", "dijit/form/TextBox", "dijit/form/Button", "dijit/Toolbar", "dijit/Tooltip", "dijit/registry",
            "dojo/_base/Color", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol",
            "esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters", "esri/tasks/IdentifyResult", "dojo/domReady!"
        ], function (
          parser, connect, array, Map, ArcGISDynamicMapServiceLayer, GraphicsLayer, Graphic, InfoTemplate, Navigation, dom, FindTask,
          FindParameters, Color, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, IdentifyTask, IdentifyParameters, IdentifyResult, registry
        )


That should look more like this

        require(["dojo/parser", "dojo/_base/connect", "dojo/_base/array", "esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/layers/GraphicsLayer", "esri/graphic", "esri/InfoTemplate", "esri/toolbars/navigation", "dojo/dom", "esri/tasks/FindTask",
            "esri/tasks/FindParameters", "dojo/_base/Color", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters", "esri/tasks/IdentifyResult", "dijit/registry",
            "dijit/dijit", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/layout/AccordionContainer", "dijit/form/TextBox", "dijit/form/Button", "dijit/Toolbar", "dijit/Tooltip", "dojo/domReady!"
        ], function (
          parser, connect, array, Map, ArcGISDynamicMapServiceLayer, GraphicsLayer, Graphic, InfoTemplate, Navigation, dom, FindTask,
          FindParameters, Color, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, IdentifyTask, IdentifyParameters, IdentifyResult, registry
        )
0 Kudos
AlexDeVine
New Contributor III
Hi Ken,

Thank you for your reply. Hmmm, I thought I had them in the correct order. I had been working under the idea that the require modules needed to be in the order that they are referenced in the javascript and that the function aliases just needed to be in the same order as the require modules. Perhaps I need to look into that more...

Unfortunately, the reordering of those components did not fix the issue with adding graphics to the map or the GraphicsLayer. It is certainly frustrating.

I have been trying to use Chrome's and Firefox's debuggers and the problem is that I am not getting a report of what actually is causing it to fail to the errback. I have been using a series of alerts and console.logs to get the location down to the "add" methods, but I don't know for CERTAIN. Any suggestion of a debugging tool that can dig into a function like the findtask execute?


Alex
0 Kudos
KenBuja
MVP Esteemed Contributor
So is the problem that you're not getting any results from the FindTask? Not getting any results back should not give you an error and go into the findErr function. Rather, that will happen if there are problem in executing the Find Task itself. Make sure you are getting results that can be loaded onto your map.

function showResults(results) {
    console.log (results.length);
    
    //display the results of the building text search
    //symbology for graphics
    markerSymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE, 20, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 255, 255]), 1), new dojo.Color([0, 255, 255, 0.25]));

   etc



Take a look at the video from a session at the 2013 Developers Summit called "Debugging Applications Built with ArcGIS API for JavaScript" to see how you can step through the code.

As for the require/function question, I don't know if the require modules have to be loaded in a particular order. However, all of the modules that are being given aliases in the "function" section ("dojo/parser", "dojo/_base/connect", etc) have come before all the modules that don't have a corresponding alias ("dijit/dijit", "dijit/layout/BorderContainer", etc). In your original code, Color would refer to "dijit/dijit".
0 Kudos
TracySchloss
Frequent Contributor
The thing that caught my eye is  you're still declaring your FindTask as using the old 'dot' style.
findTask = new esri.tasks.FindTask("http://eagle.camplan.uga.edu:6080/arcgis/rest/services/CampusMap/UGA_CampusMap_Base/MapServer");


One of the things you should do is change this to be simply:
findTask = new FindTask("http://eagle.camplan.uga.edu:6080/arcgis/rest/services/CampusMap/UGA_CampusMap_Base/MapServer");


That's part of the point of switching to AMD.

I totally agree with Ken's comments on the order of the require and aliases too.  One really basic thing I did was to add some more lines to both.  My eye wasn't always tracking the order correctly if I had to keep scrolling over to the right to see whatever I'd tacked onto the far right side.  Once I took the time to tidy that section up a bit, putting less on each line, it was a lot more obvious where I was getting off track.  If you don't have this part right, you're going to see weird behavior.  Ken's comment about putting all the non-aliases requires last is likely also part of your problem.  Don't mix those up at the top while your trying to get the requires and aliases "paired up".   Stick them at the end, right before dojo/domReady.
0 Kudos
KenBuja
MVP Esteemed Contributor
Tracy makes a good point about making the require/function section easier to visually examine. Here's an example of how I have one of my applications set up, grouping the modules. It may be overkill, but it's much easier for me when adding new modules and aliases.

require(["dojo/_base/array",
         "dojo/_base/declare",
         "dojo/_base/lang",
         "dojo/Deferred",
         "dojo/json",
         "dojo/ready",

         "dojox/gfx/fx",

         "dgrid/OnDemandGrid",
         "dgrid/Selection",
         "dgrid/extensions/ColumnResizer",
         "dgrid/extensions/ColumnHider",
         "dgrid/util/mouse",
         "dgrid/extensions/DijitRegistry",

         "dijit/MenuItem",
         "dijit/layout/TabContainer",
         "dijit/registry",

         "esri/map",
         "esri/InfoTemplate",

         "esri/dijit/Basemap",
         "esri/dijit/BasemapGallery",
         "esri/dijit/BasemapLayer",
         "esri/dijit/Scalebar",

         "modules/DVParameters",

         "agsjs/dijit/TOC",
         "dojo/domReady!"
], function (array, declare, lang, Deferred, JSON, ready,
             fx,
             Grid, Selection, ColumnResizer, ColumnHider, mouseUtil, DijitRegistry,
             MenuItem, TabContainer, registry,
             Map, InfoTemplate,
             Basemap, BasemapGallery, BasemapLayer, Scalebar,
             DVParameters
             ) {
0 Kudos
AlexDeVine
New Contributor III
Tracy,

Thank you for your response.

Strangely, removing the "dot" style constructors breaks my code for some of the constructors. Namely, the IdentifyTask.

Alex

The thing that caught my eye is  you're still declaring your FindTask as using the old 'dot' style.
findTask = new esri.tasks.FindTask("http://eagle.camplan.uga.edu:6080/arcgis/rest/services/CampusMap/UGA_CampusMap_Base/MapServer");


One of the things you should do is change this to be simply:
findTask = new FindTask("http://eagle.camplan.uga.edu:6080/arcgis/rest/services/CampusMap/UGA_CampusMap_Base/MapServer");


That's part of the point of switching to AMD.

I totally agree with Ken's comments on the order of the require and aliases too.  One really basic thing I did was to add some more lines to both.  My eye wasn't always tracking the order correctly if I had to keep scrolling over to the right to see whatever I'd tacked onto the far right side.  Once I took the time to tidy that section up a bit, putting less on each line, it was a lot more obvious where I was getting off track.  If you don't have this part right, you're going to see weird behavior.  Ken's comment about putting all the non-aliases requires last is likely also part of your problem.  Don't mix those up at the top while your trying to get the requires and aliases "paired up".   Stick them at the end, right before dojo/domReady.
0 Kudos
KenBuja
MVP Esteemed Contributor
Tracy,

Thank you for your response.

Strangely, removing the "dot" style constructors breaks my code for some of the constructors. Namely, the IdentifyTask.

Alex


That might be a sign that the function aliases aren't matching up correctly the require modules.
0 Kudos
AlexDeVine
New Contributor III
I thought the same thing, Ken, but I think all is well the lining up. I broke down the requires and function calls down into manageable sections and put the requires that do not have matching functions at the end like suggested:

require(["dojo/parser", "dojo/_base/connect", "dojo/_base/array", "dojo/on", "dojo/dom-construct", "dijit/form/CheckBox", "dijit/form/Button", "esri/SpatialReference",
            "esri/geometry/Extent", "esri/map", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/layers/ArcGISImageServiceLayer", "esri/layers/ArcGISTiledMapServiceLayer", "agsjs/dijit/TOC",
            "esri/layers/GraphicsLayer", "esri/graphic", "esri/InfoTemplate", "esri/toolbars/navigation", "dojo/dom", "esri/tasks/FindTask", "esri/dijit/Scalebar", "esri/dijit/Print", "esri/tasks/PrintTemplate",
            "esri/tasks/FindParameters", "dojo/_base/Color", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/request",
            "esri/symbols/SimpleFillSymbol", "esri/renderers/ClassBreaksRenderer", "esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters", "esri/tasks/IdentifyResult", "dijit/registry",
            "dijit/dijit", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/layout/AccordionContainer", "dijit/form/TextBox", "dijit/form/Button",
            "dijit/Toolbar", "dijit/Tooltip", "dojo/fx", "dojo/domReady!"
        ], function (
        parser, connect, array, on, domConstruct, CheckBox, Button, SpatialReference,
        Extent, Map, ArcGISDynamicMapServiceLayer, ArcGISImageServiceLayer, ArcGISTiledMapServiceLayer, TOC,
        GraphicsLayer, Graphic, InfoTemplate, Navigation, dom, FindTask, Scalebar, Print, PrintTemplate,
        FindParameters, Color, SimpleMarkerSymbol, SimpleLineSymbol, esriRequest,
        SimpleFillSymbol, ClassBreaksRenderer, IdentifyTask, IdentifyParameters, IdentifyResult, registry
        )


It appears that all is well, yet when I remove the old "dot" style constructor and use the new style, it breaks the app. I think this may be related to why my FindTask is not working.
0 Kudos
TracySchloss
Frequent Contributor
Maybe you're doing something special with your identify, but just because your identifyTask generates something that is typically called results doesn't mean you have to add that as a requirement.  I use IdentifyTask all the time and I've never added it either as a requirement or an alias, just IdentifyTask and IdentifyParameters.   Try taking that out and see if that helps.  You shouldn't have to keep using dot notation if all is well in the top section.
0 Kudos