4.19 Legend widget bug - duplicated requests

368
1
06-04-2021 05:00 PM
JoelBennett
Occasional Contributor III

Although an issue with incorrect symbology was fixed in the 4.19 Legend widget, the fix has caused new problems of a different nature. Starting in version 4.19, the Legend widget will send numerous, duplicated requests to retrieve the symbology for the same map service. In particular, for instances of MapImageLayer and TileLayer, it will send a legend request for each visible sublayer in the service (or each sublayer regardless of visibility, if respectLayerVisibility is false). These requests have the exact same URL, and the exact same response, and are therefore duplicated and wasteful.

All the Legend samples in the SDK involve instances of FeatureLayer, which don't exhibit this problem. However, to reproduce the issue, you can go to the Sandbox for the Legend widget sample, and replace the code within the second script tag with this:

require(["esri/views/MapView", "esri/widgets/Legend", "esri/WebMap"], function(MapView, Legend, WebMap) {
	var webmap = new WebMap({
		portalItem: {
			// autocasts as new PortalItem()
			id: "ab51d5972c4f4c5282ebae7a24d4fcf6"
		}
	});

	var view = new MapView({
		container: "viewDiv",
		map: webmap
	});

	view.when(function() {
		webmap.layers.forEach(function(layer) {
			if (layer.sublayers)
				layer.sublayers.forEach(function(subLayer){subLayer.visible=true;})
		});

		var legend = new Legend({
			respectLayerVisibility: false,
			view: view
		});

		// Add widget to the bottom right corner of the view
		view.ui.add(legend, "bottom-right");
	});
});

 

After replacing the code, open your browser's developer tools, and then in the browser window, click the "Refresh" button at the top-right of the page (note, this is a button in the page itself, not the browser's refresh button). By watching the network tab in your browser's developer tools, you'll watch the browser go berserk with legend requests. By my count, it makes nearly 260 legend requests to do what could be done with only 16. If you zoom in, you'll watch even more legend requests being sent for information the application already has.

The Legend widget has a cache, which is intended to prevent this kind of waste. However, as with the previous problem that resulted in incorrect symbology, it's the keys for this cache that are once again the culprit. Last time, they weren't "unique enough"; this time they're "too unique". My suggested fix previously involved using keys based upon the layers' url property, and once again it appears to solve this new problem as well. My workaround for 4.19 involves 3 find-and-replace operations in esri/widgets/Legend.js; the first two implement the use of layer URLs in the cache keys (rather than layer UID and sublayer ID), and the third prevents additional duplicated requests by using the cache to store promises (in addition to the legend responses it normally stores).

 

Part 1: Search for (in function buildLegendElementsForTools):

this._getLegendLayers(`${a.uid}-default`)

Replace with:

this._getLegendLayers(`${a.url}-default`)

 


Part 2: Search for (in function _generateSymbolTableElementForSublayer):

this._getLegendLayers(K||`${this.layer.uid}-${a.id}-default`,K)

Replace with:

this._getLegendLayers(K||`${this.layer.url}-default`,K)

 


Part 3: Search for (in function _getLegendLayers)

return r?Promise.resolve(r):this._legendRequest(g)

Replace with:

return r?((r.constructor==Promise)?r:Promise.resolve(r)):xa[a]=this._legendRequest(g)

 

 

0 Kudos
1 Reply
ReneRubalcava
Frequent Contributor II

nvm, i see

0 Kudos