Select to view content in your preferred language

How to use dynamic layers in js api 4.4

2161
4
08-17-2017 06:18 AM
roemhildtg
Occasional Contributor III

I'm confused on how I can use dynamic layers in the 4.4 api. I have a group of layers published from arcmap like this:

By default, all of the group layers are off, some of the child layers are on, and nothing is visible until the user toggles a group layer on. (this is how it works in 3.x).

In 4.4, I set up some layer like this: 

{
                id: 'assets',
                url: `${url}/internal/assets/MapServer`,
                // sublayers: [{
                //     id: 12, 
                //     visible: true
                // }, {
                //     id: 13, 
                //     visible: true
                // }],
                popupTemplate: {
                    title: 'cid: {cid}'
                }
            }

When the map loads, all of the child layers that are visible are displayed. The map looks crazy busy. 

So just to test what happens I uncomment the above code to show only sublayer 12. 

This works, only sublayer 12 is shown:

Now if I uncomment both sublayers 12 and 13 from the block above, it stops working. I get no image from the server. I checked the network logs.

In the version with no sublayers, the network image request looks like this:

layers:show:43,44,51,50,36,37,38,1,2,3,53,54,6,8,9,10,55,13,14,15,16,17,22,58,59,25,30,31,32,33

With one sublayer:

layers:show:12

With two sublayers: 

dynamicLayers:[{"id":13,"source":{"mapLayerId":13,"type":"mapLayer"}},{"id":12,"source":{"mapLayerId":12,"type":"mapLayer"}}]

My questions are: 

  • Why does providing no sublayers display the layer incorrectly (ie ignoring group layer visibility)?
  • Why do the parameters change from layers to dynamicLayers when switching from one sublayer to two sublayers? - a similar problem is observed here: https://codepen.io/anon/pen/zdpGLL?&editors=100
Tags (1)
0 Kudos
4 Replies
ThomasSolow
Regular Contributor

Thanks for the detailed write-up.  I don't know a whole lot about this subject (dynamic sublayers) so I don't know how much help I'll be but I'll give it a shot.

One big issue here is that errors are not thrown correctly when the image request fails.  For example, in the sample you posted, this request is made: rest call.  The server returns an error, but this error seems to go unhandled in the client, and as a result nothing happens.  I suspect this is what is happening when you try to get sublayers 12 and 13.  Try copying the request URL (filter network tab for export) from the network tab of dev tools into the browser and see if you get back an error when you specify sublayers 12 and 13.

In the case of the sample you posted, what goes wrong here is one sublayer (with id 4) is a dynamic layer with a different source, ie is isn't part of the Map Service.  You have to specify that this sublayer is a dynamic layer and specify its source explicitly, like in the original code sample.

Another thing I noticed while looking at this is that the server doesn't handle export calls (which, by the way, is the call that gets an image from a Map Server) with both dynamicLayers and layers.  If you have one dynamic layer, then all sublayers will be specified as dynamic layers in the export request.  This is why the parameters change from layers to dynamic layers.  For the layers that are part of the Map Service, that Map Service is their source in the dynamicLayers list, and this is specified by their id.  For other layers, not included in the Map Service, a separate source needs to be specified.  

Not being able to handle layers and dynamicLayer is either a design choice or a limitation.  But if you specify both dynamicLayers and layers on an export request, layers are ignored.

Going a little further here, looking at this example: 

layers:show:43,44,51,50,36,37,38,1,2,3,53,54,6,8,9,10,55,13,14,15,16,17,22,58,59,25,30,31,32,33

There is no sublayer with id 12 in this list.  What I think is happening here is this:

When you manually specify to include sublayers 12 and 13, the Map Server is queried for its information, including a list of sublayer ids.  The JS code then looks at this information and see that there is no sublayer with id 12.  It then sends an export request to the Map Server using dynamicLayers as it assumes that sublayer 12 must be a dynamic layer with a different source.  But a different source is not specified.  Ideally an error would be thrown here in cases where an alternate source is not specified, but maybe there are some odd edges cases where you would want to send the request.  Anyway, the request is made and fails, and that failure is not handled correctly, so there's no user feedback.

Long story short, I would try specifying sublayers with id 43 and 44, or any ids that are included in that list.  I assume all of your sublayers are sourced from the same Map Service, so you shouldn't need to worry about dynamicLayers at all.

As far as your first question, regarding visibility, I'm not sure why this isn't handled correctly.  But I think you should be able to manually specify visibility for each sublayer.

0 Kudos
roemhildtg
Occasional Contributor III

Thanks for the tips. Just an Update: If I specify the sublayers in reverse order like this:

                sublayers: [{
                    id: 13, 
                    visible: true
                }, {
                    id: 12, 
                    visible: true
                }],

It actually works! Thanks to Yann Cabon‌ for this tip. 

Just to address some of your comments:

The JS code then looks at this information and see that there is no sublayer with id 12

There is a sublayer id 12. Its the storm structures layer. 

 Anyway, the request is made and fails, and that failure is not handled correctly, so there's no user feedback.

The request appears to succeed, the server returns a status 200, but there is "No Data" in the request. Server logs on debug mode don't show any issues either. If I open up the url, the data does show an error message:

{"error":{"code":400,"message":"'dynamicLayers' is not enabled on this MapService.","details":[]}}

> I assume all of your sublayers are sourced from the same Map Service, so you shouldn't need to worry about dynamicLayers at all.

Correct, I don't actually want to use dynamic layers, I just want the default symbology, but for some reason the api is converting my request to a dynamic layers request. 

0 Kudos
ThomasSolow
Regular Contributor

Good to know you've got it working.

Ideally the server wouldn't return 200 and an error.  I'm not sure what that's about, but maybe it's unavoidable.

Would be interested to know why the order of the sublayers matter.

0 Kudos
roemhildtg
Occasional Contributor III

From the chat:

roemhildtg [10:42 AM]
Its like its getting reversed somehow


yann [10:56 AM]
well yes and no :slightly_smiling_face:


[10:56]
the ids are one order. but overall, all the layers and sublayers in the map are ordered the same way, drawing from bottom to top

0 Kudos