Book Image

Mastering ArcGIS Server Development with JavaScript

By : Raymond Kenneth Doman
Book Image

Mastering ArcGIS Server Development with JavaScript

By: Raymond Kenneth Doman

Overview of this book

Table of Contents (18 chapters)
Mastering ArcGIS Server Development with JavaScript
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Adding some action


At this point, we have a map that draws all the state and census block and track data. We need more than that. We need a way for the user to interact with the site. The ArcGIS JavaScript API incorporates many tools provided by the native JavaScript language, plus new tools provided by Dojo.

Events

When many of us learned traditional programming, we learned that programs followed a linear design. They started on the first line and ended on the last line. The computer performed each computation in an ordered fashion, and would not go on to the next line until the current line had finished.

But JavaScript adds something different. JavaScript adds an event loop that monitors for specific website interactions, such as a change in a text blank. We can attach a function, commonly called an event listener, to a known element event. When that event is triggered, the event listener runs.

For example, buttons have a click event, and if we attach an event listener to the button's click event, that function will respond every time that button is clicked. We can also get information about the button through the data passed through the click event.

For our application, we want the map to do something when we click on it. If we look up the list of supported map events, we can attach an event listener using the .on() method. The .on() method takes two parameters, a string description of the event, and the event listener function we want to be called when the event occurs. A list of supported events can be found in the ArcGIS JavaScript API documentation:

map.addLayer(layer);
function onMapClick (event) {
}
map.on("click", onMapClick);

Before we can do anything with the map, we need to know if it has loaded yet. If we're running an updated browser on our fastest computer with a high-speed internet connection, the map may load immediately, but if we're testing from a mobile browser on an older smartphone, with less than stellar internet download speeds, the map may not load very quickly.

Before we assign the click event, we're going to test whether the map has loaded. If so, we'll add the onMapClick function as an event listener to the map's click event. If not, we'll wait until the map fires its load event to set the click event. Just so we don't have to repeat ourselves when adding the map click event, we'll enclose that assignment in another function:

function onMapClick(event) {
}
function onMapLoad() {
  map.on("click", onMapClick);
}
if (map.loaded) {
  onMapLoad();
} else {
  map.on("load", onMapLoad);
}

Tasks

While developers can write code that does a lot with JavaScript, there are some tasks that are best left to a server. The ArcGIS JavaScript API sends requests to the server through task objects. There are tasks for calculating the area and perimeter of complex shapes, tasks for querying and returning spatial and non-spatial data on features in a map, and tasks for creating .pdf documents containing the map we're looking at, among many others. These tasks take the burden off the browser to perform complex calculations that could be very slow on mobile devices. They also allow the library to be lighter in weight, so the library doesn't have to load every single set of conversion factors between one coordinate system and another, for example.

Most tasks have three parts: the task object, the task parameters, and the task results. The task object lets us send requests to the ArcGIS Server for specific tasks, and includes the constants that may need to be referenced for some tasks. The task object typically takes in a URL string parameter that tells the task to which ArcGIS Server service endpoint to send its requests. The task parameters object defines what information we need to get information from the task. Finally, after we execute the task with the task parameters, and we receive the response from the server, we get a structured object, or a list of objects known as the task's result. Formats for the task, task parameters, and task results can be found in the ArcGIS JavaScript API documentation at https://developers.arcgis.com/javascript/jsapi/.

In our code, we're going to use a task called an IdentifyTask method. We'll tell the IdentifyTask method to contact ArcGIS Server through our census URL. Inside the map click event handler, we'll create a task parameter object called an IdentifyParameter object. We'll configure it with the data about the point we clicked, and data on the map. Finally, we'll execute the IdentifyTask method, passing in the IdentifyParameters object, to retrieve census data from the location we clicked:

layer = new ArcGISDynamicMapServiceLayer(censusUrl),
   iTask = new IdentifyTask(censusUrl);

function onMapClick (event) {
  var params = new IdentifyParameters();
  params.geometry = event.mapPoint;
  params.layerOption = IdentifyParameters.LAYER_OPTION_ALL;
  params.mapExtent = map.extent;
  params.returnGeometry = true;
  params.width = map.width;
  params.height= map.height;
  params.spatialReference = map.spatialReference;
  params.tolerance = 3;
  iTask.execute(params);
}

Deferreds and promises

Years ago, when FORTRAN ruled the computer programming world, there was one statement that drove developers crazy when it came time to troubleshoot their code: GOTO. With this line of code, disrupting the flow of the application, the application would jump to another line of code. Jumping from one section of code to another made following the application's logic difficult at best.

With modern JavaScript and asynchronous development, following the logic of some asynchronous applications can be difficult, too. The app fires one event when the user clicks a button, which triggers an AJAX request for data. On the successful return of that data, another event fires, which makes the map do something that takes a little time. After the map finishes, it fires off another event, and so on and so forth.

Dojo responded to this by creating Deferreds objects. Deferred objects return a promise that a result from an asynchronous process will be coming soon. The function waiting for the result will not be called until that promise is fulfilled. With functions returning Deferred results, the developer can chain functions together using a .then() statement. The .then() statement launches the first function in its parameters only after the result is fulfilled. Multiple .then() statements can be chained together with functions that return Deferred objects, leading to an orderly, and more easily readable coding logic.

In our onMapClick function, the IdentifyTask object's execute method returns a Deferred object. We'll store that deferred result in a variable, so that it can be used by another tool later:

function onMapClick (event) {
  var params = new IdentifyParameters(),
      defResults;  defResults = iTask.execute(params);
}