How to Plan a Great Map Event

At Esri Technical Support, we enjoy working with JavaScript to create powerful web applications. I’d like to take this opportunity to share different ways of listening for events in our JavaScript API with On Style Events, which is the recommended pattern for event handling. As a previous blog focused on different patterns of event handling, this blog will stick with the best practices, tips, and tricks.

Note: Click images to enlarge.

The modular On Style Events (which means something like à la mode in French) are a bit different than Connect Style Events. Why does this matter? Because On Style Events are the recommended way to listen for and handle events with the ArcGIS JavaScript API. See the screenshot below for snippets of event styles.

Snippets of Event Styles

Since version 3.5 of the JavaScript API, these event handling functions receive a single event object from which all the event object properties can be accessed. Typically, this object is called event or evt in our samples. Instead of juggling multiple objects like with Connect Style, we can now dig into one object to access the information we need. There are two ways to use the On Style Events - with and without Dojo. The syntax for these event styles can be found in the JavaScript API reference. Let’s look at a couple code snippets to compare On Style Events with and without Dojo:

on = with Dojo (on is an alias for the dojo/on module)

on(map, ’zoom-end’, function(evt) {
     console.log(evt.extent.xmin);
     console.log(evt.zoomFactor);
     console.log(evt.anchor.x);
     console.log(evt.level);
});

map.on = without Dojo (map.on means we can do this event ourselves)

map.on(’zoom-end’, function(evt) {
     console.log(evt.extent.xmin);
     console.log(evt.zoomFactor);
     console.log(evt.anchor.x);
     console.log(evt.level);
});

By examining the above code snippets, we can see that the main difference when using On Style Events is in what the event listeners return. We can also see similarities among the new styles of event handlers, but there are important differences worth exploring.

Not bad, right?

For more better understanding, here’s a real-world example. You can follow along at home with the JavaScript Events application hosted on jsfiddle.net. Use the following instructions to follow along (I used Google Chrome for this example):

1. Open the application in your browser.

2. Press F12.

3. Navigate to the Console Tab, if not open already.

The following screen displays:

JSFiddle

This application shows the functionality of dynamic layers and our elegant dark gray basemap tiles (you can also try the application live here: JavaScript Events application on GitHub). As you zoom in and out of the map, different layers become visible as indicated in the lower-left information box. There are six event listeners in this application. Let’s go through them one by one and see what they do.

1) map.on(“load”, function()

When the map first loads, it immediately runs the unnamed function. This listener will only be called once while the application is running, and the listener does not take any arguments in the function. The purpose is to define the four other event listeners and to call the updateScale() function. This allows the scale to be defined in the information box without panning or zooming.

2) map.on(“zoom-end”, updateScale)

After zooming in or out of a map, this event listener will call the updateScale() function. This function updates the map scale in the information box and in the Console tab. This listener does not take any arguments in the function, either.

See below for the event handler:

function updateScale() {
     dojo.byId("map-scale").innerHTML = 
       dojo.number.format(parseInt(map.getScale()));
     console.log("Map scale: " 
       + dojo.number.format(parseInt(map.getScale())));
}

3) map.on(“pan-end”, updateExtent)

When a user pans around the map, this event listener will call the updateExtent() function, which will update the map extent in the Console tab. This listener takes the generic evt argument in the function.

Pro tip: There are many other attributes that you can dig out of the evt object. To see what is available, use the following steps (I used Google Chrome for this example):

1. Press F12 to open the developer’s tools.

2. Navigate to the Source tab.

3. Find the section of code with this event handler (around line 170).

4. To set a breakpoint, click the line number to the left of the code.

See below for a screenshot of this process.

Breakpoint in Sources tab (Google Chrome)

5. Refresh the application, and when the application pauses on the breakpoint, switch to the Console tab and type “evt” into the prompt.

You can now expand the evt object to see what’s there and experiment with how to call it. View the screenshot below to see how the evt appears in the Google Chrome Console tab.

evt in Console tab with Google Chrome

See below for the event handler:

 function updateExtent(evt) {
     console.log("Map extent");
     console.log(" XMin: " + evt.extent.xmin);
     console.log(" YMin: " + evt.extent.ymin);
     console.log(" XMax: " + evt.extent.xmax);
     console.log(" YMax: " + evt.extent.ymax);
}

4) map.on(“zoom-start”, updateOldLevel)

When a user zooms in or out of the map, as soon as the zooming action starts, this event listener will call the updateOldLevel() function. This updates the zoom level of the map in the Console tab. Again, the listener takes the generic evt argument in the function.

Please see below for the event handler:

function updateOldLevel(evt) {
     console.log("Map zoom level was: " + evt.level);
}

5) map.on(“zoom-end”, updateNewLevel)

When a user zooms in or out of the map, as soon as the zooming action stops, this event listener will call the updateNewLevel() function. This updates the zoom level of the map in the Console tab. Notice that it again takes the generic evt argument in the function.

Please see below for the event handler:

function updateNewLevel(evt) {
     console.log("Map zoom level is: " + evt.level);
}

6) usaLayer.on(“load”, load)

When the application first loads the usaLayer map service, this event listener calls the load() function, which displays the minScale values for each layer in the Console tab. If you open the map service from REST (http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer) and compare the minScale values for each layer, you see that the dynamicLayerInfo class in the code overrides each layer, which is pretty interesting. Notice that it again takes the generic evt argument in the function.

Please see below for the event handler:

function load (evt) {
     console.log("layer 1 minScale: " 
       + evt.layer.dynamicLayerInfos[0].minScale);
     console.log("layer 2 minScale: " 
       + evt.layer.dynamicLayerInfos[1].minScale);
     console.log("layer 3 minScale: " 
       + evt.layer.dynamicLayerInfos[2].minScale);
     console.log("layer 4 minScale: " 
       + evt.layer.dynamicLayerInfos[3].minScale);
}

For most of you, this is a refresher about working with On Style Events and the JavaScript API. But also for most of you, this will be new and exciting information to take your web apps (and salaries) to the next level. Let’s take a minute to review what we learned here. On Style Events have been around for a while and are slightly different than Connect Style, but are just as easy to use. On Style Events are simple and powerful ways of listening and handling many different event patterns. You can dig into all the arguments in the Console tab by setting a breakpoint and calling the argument object “evt”.

Please consider reading our Concepts documentation for more information about working with events in the JavaScript API:

https://developers.arcgis.com/javascript/jshelp/inside_events.html

Stay tuned until next time, when we discuss how to make your map “pop” with the new dojo.redecorate method. Happy eventing!


Noah S. – SDK Support Analyst

This entry was posted in SDK, Support.Esri.com and tagged , , , . Bookmark the permalink.

Leave a Reply