3

I am using some stock print templates like the 2 in this sample. The problem is that the legend doesn't show up at all. I found a few forum questions showing problems with the legend but none of them involved having no legend at all. My code looks like this ...

    var legendLayer = new LegendLayer();
    legendLayer.layerId = "Parcels_and_Zoning"; 
    legendLayer.subLayerIds = [4, 10];

The LegendLayer is included in the require section "esri/tasks/LegendLayer" and using typeof(legendLayer), it is an object. None of the samples that I have found show where to include space for the legend so maybe that is where things are going wrong. This next bit of my code is almost directly from the sample that I linked above ...

        var layouts = [{
        name: "Letter ANSI A Landscape", 
        label: "Landscape (PDF)", 
        format: "pdf", 
        options: { 
          legendLayers: [legendLayer], // empty array means no legend
          scalebarUnit: "Miles",
          titleText: printTitle + ", Landscape PDF" 
        }
      }, {
        name: "Letter ANSI A Portrait", 
        label: "Portrait (Image)", 
        format: "jpg", // ETC. ETC. 

Note the comment saying "// empty array means no legend". I took the legendLayers option out entirely and STILL get no legend. Does anyone have any idea what I am doing wrong? I considered that I may need to add a legend in the html but I only need it for printing (I have not fully explored this). Do I need to create a legend in some way other than the code I've provided (the samples don't indicate this at all and all seem to avoid having a legend)? Is it possibly a problem with the service I have created ? The screenshot shows the result with no legend and sublayer 10 is the pink and amber colored polygon layer that I was hoping to get in the legend. screenshot

5
  • I'd also be interested in knowing why the units in the scalebar don't magically change by simply using "Feet" instead of "Miles" in the "scalebarUnit" option (possibly related?). Commented Oct 10, 2014 at 15:04
  • Did you ever get this working? I work with printing a lot, but it seems like you're doing everything right (as far as i can tell). If you're using your own custom layouts, then make sure you have a placeholder tag for legend. Don't worry about the HTML layout, has nothing to do with it.
    – janechii
    Commented Oct 13, 2014 at 19:55
  • I'm going through with a support ticket currently. Thanks for your comment. It is useful to know that I don't need to include the html legend. Commented Oct 14, 2014 at 14:53
  • As it turns out from what support sent me, it looks like the html legend is required after all. Something like ... var legend = new Legend({map: map}, "legendDiv"); legend.startup(); Commented Oct 15, 2014 at 14:58
  • And this worked for you? I am quite surprised! Then again, ESRI printing is a sort of a black box. Even the sample linked in your question doesn't have the HTML element and Legend in print comes out fine. Try it out in the sandbox: developers.arcgis.com/javascript/sandbox/…
    – janechii
    Commented Oct 15, 2014 at 15:04

2 Answers 2

6

I spent hours trying to figure out the same issue. I was passing the LegendLayer objects with the layerId as it is defined in the arcgis MapServer service, and no legend showing at all. Finally, I realized that I had to pass the OPERATIONAL LAYERS, in those ids (Sniffing the JSON that it sends to ExportWebMap). So for example, it turned to be layerId = "layer1" and subLayerIds = [11, 21], and it generated perfectly the legend, with only the 11 and 21 layers. LegendLayer.layerId property stands for the assigned ID string of the layer in the map, not in the service.

Hope it had helped you everyone.

4
  • 1
    Thanks for your answer. This may be very helpful. The API documentation is very unclear about what LegendLayer.layerId is. I'm not sure how to sniff the JSON (my parents warned me about that kind of thing). How would I do that? Are you saying that if the layer I want is at the top of the TOC in the mxd that was used to share the service, that is going to be layer0 and the 2nd layer would be layer1 etc. ? If not, how can I determine what the assigned ID string is? Commented Oct 17, 2014 at 19:53
  • 1
    I meant: Capturing the HTTP Request via Chrome console (Network tab), and see what it sends hehehe ;). In the mxd, layers are feature classes, that is, collection of objects that share the same kind of geometry and spatial reference, etc., but in the ArcGIS javascript API, layer is an object that handles arcgis server resources in a url (In this case, ArcGISDynamicMapServiceLayer). Inside that URL, we could have many layers (the ones exposed in the mxd). The API assigns a string ID for each layer added to the map. "layer0" should be the basemap layer, "layer1" and so on. For example:
    – Rorro
    Commented Oct 20, 2014 at 13:23
  • 1
    var layer = new ArcGISDynamicMapServiceLayer("server.arcgisonline.com/ArcGIS/rest/services/Demographics/…); map.addLayer(layer); // layer.id will hold the layerId value needed...
    – Rorro
    Commented Oct 20, 2014 at 13:24
  • Yes. That last comment was very helpful. I still need more map space for the legend that I want to use (doesn't show because it is too big) but I see where the ID comes from and can add a simple legend. Commented Oct 20, 2014 at 14:58
4

To clarify Rorro's answer, the layer id is not the same as the layer name. You can save yourself a lot of time using the following code (where mylayer references your map service layer):

var legendLayer = new esri.tasks.LegendLayer();
legendLayer.layerId = mylayer.id;

The layer id will differ depending on how you consume the service. E.g. Rorro said his layer id turned out to be "layer1", I assume he was using esri.layers.ArcGISDynamicMapServiceLayer. I on the other hand used esri.layers.FeatureLayer which has a layer id of "graphicsLayer2".

Also if you try to obtain your layer id with console log:

mylayer = new esri.layers.FeatureLayer("http://www.arcgis.com/arcgis/rest/services/boundary/MapServer/1", {
    mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
    outFields: ["OBJECTID"]
});
console.log(mylayer.id)

Will result in null, I guess this method is asynchronous. So you can put a timed delay on it or call console log from a button.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.