WebMap JSON gathered by printTask for GP Service reflects current state of map?

1245
6
09-17-2020 09:00 AM
Arne_Gelfert
Occasional Contributor III

So I'm needing a simple clarification here: 

When using JSAPI to pass the webmap's JSON to a GP service, what's actually gathered by...

webMapAsJSON = printTask._getPrintDefinition(currentMap, params);

... is the current state of the map, right? Layers that are turned off  (hidden) won't be passed along?

On a previous project I was working on, I had no trouble massaging the webmap inside my GP service to selectively turn things on/off to generate a variety of PDF products. Now, I'm noticing that the JSON is missing any layers that are turned off. Might be a no brainer but I want to confirm this is expected behavior.

Workaround would be to turn on all layers before printTask is called.

Or is there a way to reference the JSON of a webmap in Portal if essentially all the layers in my app derive from the webmap? But that wouldn't have info such as extent they way I needed. Darn! Thanks for any feedback.

0 Kudos
6 Replies
Arne_Gelfert
Occasional Contributor III

Let me modify the direction of my inquiry as I've thought through this further. So I have an event handler hooked up to a button that calls my printTask. I can make this same event add any layers to the map that I want passed in the JSON. But that has the seemingly inexplicable effect for the user why different layers now showing up in map and/or legend. Is there a simple way to grab the JSON, replace/update the layer info I want include and then feed it into my GP processing service, thereby avoiding the map refresh/change? Right now, the only way I can envision is by brute force string manipulation. 

0 Kudos
Noah-Sager
Esri Regular Contributor

I'm not 100% sure I'm tracking with you, but if you want to make some modifications to a call to the print service after a user clicks the button, you could use a request interceptor.

config | ArcGIS API for JavaScript 4.16 

0 Kudos
Arne_Gelfert
Occasional Contributor III

Haha - sorry for not speaking more clearly, Noah. Basically, I want to capture the JSON for the current webmap in a variable...

let webMapAsJSON = printTask._getPrintDefinition(currentMap, params);
let webMapAsJSONasString = JSON.stringify(webMapAsJSON);

... then I want to sneak in the JSON for some layers that are belong to the underlying webmap coming out of Portal but without modiifying what's showing in the map. (Working on custom widget for WAB, so I'm getting my map services via reference to a webmap item in Porta,.)

I've been playing with some Javascript to basically add/modify portions of the JSON myself. I had merely hoped somebody had some ArcGIS specific snippets to share.

0 Kudos
Noah-Sager
Esri Regular Contributor

Gotcha, that makes more sense now. I do not know offhand, but I bet if you play around with printing some different layers and extents, you could get a sense for what the JSON looks like. And use something like a JSON formatter to verify that it's legit

https://jsonformatter.org/ 

and still use the requestInterceptor to sneak it into the request. But perhaps someone else in the community has more experience with this sort of workflow.

0 Kudos
TanuHoque
Esri Regular Contributor

Hi Arne Gelfert

Now, I'm noticing that the JSON is missing any layers that are turned off.

I think it was done for optimization reason since those layers would be drawn any way and passing them are basically unnecessary for a print service.

I agree what Noah Sager‌ suggested.

As you know there are a lot of similarity between webmap_json (for print service) and the json definition of portal items -- but they are NOT the same. Therefore in many cases, you can simply get the json from a portal item and inject that in webmap_json using Noah's suggested method and it should work in most of the cases.

Sorry couldn't help you much.

Tanu

Arne_Gelfert
Occasional Contributor III

Tanu Hoque‌, Noah Sager‌ - so I've looked at this again, and notice that in the JSON under operational layers, in fact, I get this...

"operationalLayers": [
  {
    "id": "defaultBasemap",
    "title": "World Topographic Map",
    "opacity": 1,
    "minScale": 0,
    "maxScale": 0,
    "url": "https://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"
  },
  {
    "id": "My_Map_365",
    "title": "My_Map",
    "opacity": 1,
    "minScale": 0,
    "maxScale": 0,
    "url": "HTTPS:// ...<MapService URL>",
    "layers": [
      {
        "id": 1,
        "layerDefinition": {
        "source": {
        "type": "mapLayer",
        "mapLayerId": 1
          }
        }
     },
     {
        "id": 2,
        "layerDefinition": {
        "source": {
        "type": "mapLayer",
        "mapLayerId": 3
          }
        }
      },

...MORE ...‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Since I'm trying to consume the JSON in a GP Service. The easiest to do is just to drop the "layers" key entirely. That way the GP service gets fed all the sublayers of the Map Services, which is specific by URL, and I weed through what I want to show using Python. Didn't realize this was working. I saw the additional layers and thought only those showing were passed through. If I leave the "layers" key, then I end up with duplicate layers on the Python side of the fence, which makes it unworkable. Anyway, thanks for chiming in. Now, I just need to figure out why some layers refuse to turn of using arcpy.