imageparameters.layerDefs does not work with 10.5

11118
44
Jump to solution
01-10-2017 10:14 AM
DuarteCarreira
Occasional Contributor II

It seems REST API in 10.5 deprecated simple sintax on layerDefs:

ArcGIS REST API 

Simple syntax is not supported as an expected value for layerDefs parameter starting 10.5.

This is pretty hidden in the documentation by the way...

As a side effect, it seems imageparameter.layerDefinitions no longer works since it still translates requests to the simple sintax:

ImageParameters | API Reference | ArcGIS API for JavaScript 3.19 

In our server we get an error when debugging http requests on the browser's console:

{"error":{"code":400,"message":"Invalid 'layerDefs' is specified","details":[]}}

Our code is pretty simple and worked last week against a 10.3 server.

Can anyone reproduce and confirm this?

EDIT: Just to add that the simplest sample from esri does not work against a 10.5 server:

Layer definitions on a dynamic map service | ArcGIS API for JavaScript 3.19 

It seems a bug to me... I wish I'm proven wrong...

Thanks.

44 Replies
JordanPorter
New Contributor III

Its very simple, i just loop through all the dynamic layers in the map, and apply your "patch"

I load it in the header, and since i wanted to be able to just load it in any code ive written, it wont know when the layers will all be loaded, and i didnt want to have to add ANYTHING else to any of the apps.  So the timeouts are just waiting and trying again, not pretty i know, but it allows me to not have to add any support code in the apps themselves.

I wanted something that would just loop through any dynamic layer, so this is what i've implemented.  Though it's FAR from ideal, It's worked great so far.

function patch() {
    if (map) {
        if (map.loaded) {
            var patchDebug = true
            if (patchDebug) {
                console.debug("Applying 10.5 Patch")
            }
            jQuery.each(map.layerIds, function (index, value) {
                map.getLayer(value).on('update-start', function (evt) {
                    //console.log("Original layerDefs:" + evt.target._params.layerDefs);
                    try {
                        if (evt.target._params) {
                            if (evt.target._params.layerDefs) {
                                if (evt.target._params.layerDefs.charAt(0) != '{') {
                                    //if not json syntax, convert
                                    evt.target._params.layerDefs = evt.target._params.layerDefs.split(':').join(':"').split(';').join('",') + '"';
                                    evt.target._params.layerDefs = '{' + evt.target._params.layerDefs + '}';
                                }
                                if (patchDebug) {
                                    console.log("Patch Corrected " + evt.target.id + " defQ to: " + evt.target._params.layerDefs);
                                }

                            }
                        }
                    }
                    catch
                        (err) {
                        if (patchDebug) {
                            console.error(err)
                        }
                    }
                });
                map.getLayer(value).refresh()
            })
        }
        else {
            window.setTimeout(function () {
                patch()
            }, 1000)
        }
    } else {
        window.setTimeout(function () {
            patch()
        }, 1000)
    }
}
window.setTimeout(function () {
    patch()
}, 5000)
DavidWendelken
Occasional Contributor

Great workaround!  

We ran into this problem in web appbuilder's Filter widget.  You saved us many hours of figuring out what was wrong and how to go about fixing it. 

I put this in the filter widget's widget.js file at the bottom of the postCreate method and it worked like a champ:

for (var i = 0; i < this.map.layerIds.length; i++) {
    this.map.getLayer(this.map.layerIds).on('update-start', function (evt) {
        try {
            if (evt.target._params) {
                if (evt.target._params.layerDefs) {
                    if (evt.target._params.layerDefs.charAt(0) != '{') {
                        //if not json syntax, convert
                        evt.target._params.layerDefs = '{' + evt.target._params.layerDefs.split(':').join(':"').split(';').join('",') + '"' + '}';
                    }
                }
            }
        }
        catch (err) {
        // haven't figured out what to do here...
        }
    });
    this.map.getLayer(this.map.layerIds).refresh();
};
0 Kudos
DavidWendelken
Occasional Contributor

Updated the portal's version of web appbuilder (as opposed to the stand-alone web appbuilder tool I posted about above) to use the same code snippet.  Placed it at the bottom of the Filter widget's startup method.  Worked like a champ.

(Also made sure I made a list of the changes so when they get overwritten by a new Portal version, I'll know what changes need to be investigated and potentially re-applied.)

0 Kudos
AlessioDi_Lorenzo1
New Contributor III

Hi, 

thanks for the workaround.

Can you help me to figure out how to apply it to the definitions array in an identify task? 

It seems a "start" event is not available for identify, so the invalid definition expression error still remain.

0 Kudos
DuarteCarreira
Occasional Contributor II

Hi there Lorenzo.

I really think esri has to increase this bug priority. This is going to bubble up in many, many applications. I am amazed geonet is not buzzing with people complaining about this.

I don't have a solution for the issue with identify request... it's the same thing but there's no specific event to that request.

I don't think request.setRequestPreCallback(callbackFunction) works with identify but I haven't tested that (it doesn't work with export request for sure).

What might work is to use dynamicLayers in identifyParameters instead. I know this works in export, so it must also work with identify. You can specify pretty much everything you want with dynamicLayers, like the definitionquery, symbology, etc. It's pretty complicated though, but there are samples out there.

Another option I thought of when searching for a solution to the initial problem was to use a proxy that just corrects the layerDefs parameter in every request that passes through it.

You can easily modify esri's proxy to do that, and use the proxied url instead of the direct mapservice url. I think this is the easiest way and also the broader solution because it will catch and correct every request you send its way.

But the only *perfect* solution has to come from esri. So my best advice is to get them on the phone.

AlessioDi_Lorenzo1
New Contributor III

thank you Duarte,

maybe the less problematic way for me is to roll back to 10.4.1

Fortunately I just have to reinstall the web adaptors.

I expect ESRI fix this asap! Otherwise 10.5 will remain unuseful for anyone having a production environment with web applications running.

0 Kudos
GreggRoemhildt1
Occasional Contributor

Thanks for posting these workarounds and reports. 

It doesn't seem so much as a bug as a planned breaking change that should have been updated in the js api prior to releasing 10.5...Seems like a scary lack of communication between the js team and the server team. 

0 Kudos
DuarteCarreira
Occasional Contributor II

Gregg, yes it seems that way. What I feel most scary is the absence of awareness or communication from esri. If you look at the bug description it seems unaware of any critical level assessment. It's just one more bug to the pile.

Also, how can we shout out to someone from esri to this thread? Maybe using some name tags will work?

jskinner-esristaff

nicolaraluca

odoe

0 Kudos
GreggRoemhildt1
Occasional Contributor

Do you know what the bug number is? For potentially helpful tracking in the future?

0 Kudos
DonKang
New Contributor III

BUG-000102051
You can find it my posting towards the top.