I have tried the GeometryEngine.union method (within JavaScript 3.15 API) but it throws the following error when it is placed within a try-catch statement:
TypeError: Unable to get property 'hq' of undefined or null reference
It seems to work when not placed within a try-catch, but since it is throwing this error I'm concerned about using it within a production application. Also, the equivalent Union method in the ArcGIS Server GeometryService does not throw an error.
I thought the error might be due to undefined spatial references in the array of geometries passed to it, but I have checked and they are all defined.
Can anyone please advise why this error is being thrown?
arrayUtils.forEach(AdviceGlobal.savedFeaturesGraphicsLayer.graphics, function (savedGraphic) { // Define spatial reference for geometryEngine var thisGeometry = savedGraphic.geometry; console.log(thisGeometry.spatialReference); if (thisGeometry.spatialReference == null) { thisGeometry.spatialReference = map.spatialReference; } geometryToCapture.push(thisGeometry); }); // Try geometryEngine try { var unionedGeometry = geometryEngine.union(geometryToCapture); saveFeature(unionedGeometry); } catch (e) { onUnionError(e); }
I too have had the same issue, which has been occurring since geometryEngine's introduction in 3.13. I hadn't noticed (and therefore can't verify) the try/catch issue since my code doesn't have any of those clauses around this operation. My code executes the combine operation inside of a callback from a QueryTask, so there's probably a try/catch somewhere up the call stack in the JavaScript API.
Since I'm not the only person this is happening to, I was emboldened to look into this further. Unfortunately, the code for geometryEngine is much too obfuscated to readily understand what's going on, but here's the function where things foul up:
b.prototype.iL=function(a){ for(var d=[],c=[],h=this.sn,l=b.bc(h),g=0;g<l.length;g++){ var m=l,n=h if(this.Fc||1E4<n.hq&&1<n.Ci.length){ this.bp-=n.Ci.length; for(this.Qo-=n.Ci.length;0<n.Ci.length;) d.push(n.Cv().hw),n.OQ(); c.push(m) } } for(g=0;g<c.length;g++) delete h[c; ]; return d };
The error is thrown when comparing if 1E4 is less than n.hq, and occurs because n is undefined. If we look further up, we see n was set to the value of h
I use a locally hosted version of the API, and so I tweaked it a little to check for a valid value of n before proceeding.
Therefore, the original code (which you can ctrl-f to find):
if(this.Fc||1E4<n.hq&&1<n.Ci.length)
became
if((n)&&(this.Fc||1E4<n.hq&&1<n.Ci.length))
This appears to have fixed the problem, although I haven't performed any rigorous testing...as such, if you try this, proceed with caution. Also, if you do, you'll probably need to delete temporary internet files before reloading your app to ensure you get the updated version.
ESRI did not fix this bug in version 3.16 of the ArcGIS API for JavaScript.
ESRI has not fixed this bug in version 3.17 of the ArcGIS API for JavaScript, either.
Thanks Ken...I also have confirmed this is still an issue in 3.17.
Have you tried simplifying the geometry before doing it union?
Before pushing the geometry to array 'geometryToCapture' simplify using geometryEngine and if the result is valid then only consider that geometry for union.
This hasn't been fixed because there hasn't been a bug report logged for it. Once somebody logs as a bug it will be looked at and fixed.
This still seems to be an issue with 3.21?
I'm trying to do a simple union of two polygons and I get a TypeError at the exact same line as shown above by Joel Bennett. I don't have any try-catch and the spatialReference (32188) is the same for both polygons. I tried geometryEngine.simplify on each of those polygons before doing a union on them, but it didn't help. The union of the GeometryService works fine. What am I doing wrong with geometryEngine.union?
Update: I tried to figure out how I could apply a fix to that problem function at runtime, but it's not accessible from outside geometryEngine. So I ended up doing something similar to Joel Bennet. I recreated my own version of the geometryEngine (I called it app.geometryEngine), replaced the define at the top from esri/geometry/geometryEngine to app/geometryEngine and also added the "if (n)" at the same problem line. Everything seems fine now. Will update if that changes in the future.
I've missed a few releases, being busy with other things, but have found this is still an issue in 3.23. I haven't tried union this time around, but it happens with buffer. The workaround is still the same, although some variable names have changed.
Look for
if(this.Ec||1E4<u.jq&&1<u.Ci.length)
Replace with
if((u)&&(this.Ec||1E4<u.jq&&1<u.Ci.length))
Just tested this out with 3.23, 4.6, 3.24, and 4.7 in Chrome, FF, Edge, IE11 and can't repro. Do you have a repro case to test with?
It's possible this was already fixed somewhere along the line. Tried union, buffer, and geodesicBuffer.
Thanks!