Select to view content in your preferred language

Definition expression only applies to some of the data instead of all of it

2441
17
04-02-2019 09:34 AM
MKF62
by
Frequent Contributor

I create a definition expression on a featureLayer through it's relationship with table. The definition expression gets applied to the table first, then the definition expression for the featureLayer is created and applied. The definition expression is pulling records of a certain year in the table, then through it's relationship with the featureLayer I get GUIDs of those that match the pulled records in the table and set the featureLayer's definition expression based on those GUIDs. The problem is that for some years this works and for others it doesn't. I can see in the debugger that the definition expression gets created correctly for the featureLayer, but when I apply it to the featureLayer, nothing displays on the map. If I switch the year to another year, the definition expression gets applied and the appropriate polygons appear for that year. If I switch back to the previous year, again, no polygons are displayed, even though they exist for that year. It's pretty odd behavior and I'm not sure why this would be happening.

Records in the table when the definition expression is set to YearTreated = 2015.

Records in the related feature layer that match these MgmtTractIDs

My code should produce a definition expression like this for application to the featureLayer:

var de = "MgmtTractID = '{...}' OR MgmtTractID = '{...}' OR MgmtTractID = '{...}'

..so on and so forth

Apply that definition expression to the feature layer and I get nothing displayed on the map. This definition expression works for 2009, 2010, 2011, 2012, 2013, 2014, 2017, 2018, and 2019. It doesn't work for 2008, 2015, or 2016. I have checked and rechecked that the DE is being created correctly with formatting and that the MgmtTractIDs do indeed show up in the related feature layer. Everything looks fine. 

on(dom.byId("data-year"), "change", function () {
    var year = dom.byId("data-year").value;
    //Defintion expressions are already set upon first load of the map, don't need to recalculate
    //if the year hasn't been changed. A change event is fired on load of the map.
    if (year !== currentYear) {
        hbMgmtTableFL.setDefinitionExpression('YearTreated = ' + year);
        hbMgmtTableFL.refresh();
        //The habitat management feature layer needs to be filtered using the related table.
        getTractDefExpression();
    }
});

function getTractDefExpression() {
    var recordIDs = new Query();
    recordIDs.where = "1=1";
    hbMgmtTableFL.queryIds(query, function (OIDs) {
        if (OIDs !== null) {
            //Create relationship query
            var relatedRecordsQuery = new RelationshipQuery();
            relatedRecordsQuery.objectIds = OIDs;
            relatedRecordsQuery.outFields = ["MgmtTractID"];
            relatedRecordsQuery.relationshipId = 0;
            hbMgmtTableFL.queryRelatedFeatures(relatedRecordsQuery, function (fset) {
                //Get all MgmtTractIDs for the current year from the table
                //The table already has it's definition expression set, so it'll
                //only pull the MgmtTractIDs for the year that is set
                var MgmtTractIDsArr = [];
                for (i = 0; i < OIDs.length; i++) {
                    var OID = OIDs[i];
                    var features = fset[OID].features;
                    var mgmtTractId = features[0].attributes.MgmtTractID;
                    if (!(MgmtTractIDsArr.includes(mgmtTractId))) {
                        MgmtTractIDsArr.push(mgmtTractId);
                    };
                }
                //Create the definition expression for the feature layer
                var whereClause;
                for (i = 0; i < MgmtTractIDsArr.length; i++) {
                    if (i == 0) {
                        whereClause = "MgmtTractID = '" + MgmtTractIDsArr[i] + "'";
                    }
                    else {
                        whereClause = whereClause + " OR MgmtTractID = '" + MgmtTractIDsArr[i] + "'";
                    }
                }
                //Set the polygon feature layer's definition expression based on the GUIDs
                debugger;
                hbMgmtTractFL.setDefinitionExpression(whereClause);
                hbMgmtTractFL.refresh();
            });
        }
        else {
            debugger;
            hbMgmtTractFL.setDefinitionExpression('MgmtTractID = 0');
            hbMgmtTractFL.refresh();
        }
    });
};‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Tags (1)
0 Kudos
17 Replies
MKF62
by
Frequent Contributor

That gives me the same detail page as above: 

Not sure if you saw my edit to my last post. The request URL for 2008 data is quite different than other years.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Molly,

  Are any of the ones that are successful using the proxy? 

0 Kudos
MKF62
by
Frequent Contributor

Yes, for comparison, this is what a successful one looks like:

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Molly,

  So when the method is Post then it succeeds when it is Get it fails, which is logical. When a query string gets to big the proxy should automatically switch to Post instead of Get. In your proxy.config how specific is your serverUrl? Meaning do you have https://....org/.../rest/services/blah/blah/MapService/blah?

0 Kudos
MKF62
by
Frequent Contributor

My serverUrls are not terribly specific (we had a long thread a long time ago where we hashed it out actually ). They look like this:

<!-- Testing environment -->
<ProxyConfig allowedReferers="*"
             mustMatch="true"
             logFile="proxyLog.txt"
             logLevel="Warning">
    <serverUrls>
      <serverUrl url="https://www.xxx.org/xxx/rest/services/HabitatManagement/HabitatManagement/GPServer"
                 username="x"
                 password="x"
                 matchAll="true"/>
      <serverUrl url="https://www.xxx.org/xxx/rest/services/HabitatMonitoring/HabitatData/MapServer"
                 username="x"
                 password="x"
                 matchAll="true" />
      <serverUrl url="https://www.xxx.org/xxx/rest/services/HabitatMonitoring/HabitatClassification/GPServer"
                 username="x"
                 password="x"
                 matchAll="true" />
      <serverUrl url="https://www.xxx.org/xxx/rest/services/PrintHabitatMaps/PrintHabitatMap/GPServer"
                 username="x"
                 password="x"
                 matchAll="true" />
      <serverUrl url="https://www.xxx.org/xxx/rest/services/ShipData/ShipData/GPServer"
                 username="x"
                 password="x"
                 matchAll="true" />
    </serverUrls>
</ProxyConfig>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Proxy line in JS looks like this:

urlUtils.addProxyRule({
    urlPrefix: "https://www.xxx.org",
    //When switching between testing/development, make sure the change allowedReferers, etc. in proxy.config as well
    //For production environment (publishing)
    //proxyUrl: "/FocalAreas/proxy/proxy.ashx"
    //For testing in development environment
    proxyUrl: "/proxy/proxy.ashx"
});‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Just for the sake of testing, I added more dummy parameters to the end of the 2008 query and after I did that, the method is sent as POST and the data shows up as it should.

//Create the definition expression
var whereClause;
for (i = 0; i < MgmtTractIDsArr.length; i++) {
    if (i == 0 && i == MgmtTractIDsArr.length - 1) {
        whereClause = "MgmtTractID IN ('" + MgmtTractIDsArr[i] + "')";
    }
    else if (i == 0) {
        whereClause = "MgmtTractID IN('" + MgmtTractIDsArr[i] + "', ";
    }
    else if (i !== 0 && i !== MgmtTractIDsArr.length - 1) {
        whereClause = whereClause + "'" + MgmtTractIDsArr[i] + "', ";
    }
    else {
        whereClause = whereClause + "'" + MgmtTractIDsArr[i] + "'";
    }
}
//Set the polygon feature layer's definition expression based on the GUIDs
var de = hbMgmtTableFL.getDefinitionExpression();
if (de == "YearTreated = 2008") {
    whereClause = whereClause + "'{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}')";
}
else {
    whereClause = whereClause + ')';
}
hbMgmtTractFL.setDefinitionExpression(whereClause);
hbMgmtTractFL.refresh();

The 2008 query has 29 records. The 2009 query has 24 and is sent as a GET successfully, so it must be under the character limit.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Molly,

  Has your IT Dept set a custom queryString limit on your web server?

0 Kudos
MKF62
by
Frequent Contributor

Nope, it doesn't look like it, but I'm going to talk with someone else and see if he's got any ideas. The query works if it's 28 records or 30 records, but not 29. The number of characters in the whereClause variable for 28 records is 1191 and for 30 records it's 1275, so if nothing else, I can find a workaround where if the number of characters are between those two values, then I can tack on a dummy value to get it where it needs to be. I don't like this solution very much, but I've got nothing left in the arsenal.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Sorry I am out of ideas then

0 Kudos