The following code will execute fine with only one deferred, but more than one, 'all.then()' never executes.
(Overall, I am trying to validate a set of geometries to ensure they are not too big before adding to the map)
Any help would be very much appreciated. Thanks!
var defListArray = [];
array.forEach(layer.featureSet.features, function (feat) {
var geom = feat.geometry;
defListArray.push(that.validateFieldSize(geom));
});
//var defList = new DeferredList(defListArray); //Does not work with DeferredList as well; same behavior
all(defListArray).then(lang.hitch(this, function (results) {
//PROBLEM: This code only executes when there is only one Deferred in array
// I want to know when
console.log('deferred list', results);
}));
//...//
validateFieldSize: function(fieldGeom){
var that = this;
var deferred = new Deferred();
this.geometryService = new GeometryService(this.geometryServiceURL);
this.geometryService.on('areas-and-lengths-complete', lang.hitch(this, 'showVerifyiedFieldGeometryResults', deferred));
//setup the parameters for the areas and lengths operation
var areasAndLengthParams = new AreasAndLengthsParameters();
areasAndLengthParams.lengthUnit = GeometryService.UNIT_FOOT;
areasAndLengthParams.areaUnit = GeometryService.UNIT_ACRES;
areasAndLengthParams.calculationType = 'geodesic';
this.geometryService.simplify([fieldGeom], function (simplifiedGeometries) {
areasAndLengthParams.polygons = simplifiedGeometries;
that.geometryService.areasAndLengths(areasAndLengthParams);
});
//deferred.resolve('QUICK RESOLVE'); //'all().then()' executes if I comment this line out...
return deferred;
},
showVerifyiedFieldGeometryResults: function(deferred, results){
var acres = Math.floor(results.result.areas[0]);
//NOTE: Check acres to ensure the feature is not too big... code omitted...
console.log('geometry results'); //this line always executes so it appears something is wrong with the Deferreds...
deferred.resolve('Verified Field Size: ' + acres);
}
Solved! Go to Solution.
I guess I don't understand why you need deferreds when the geom service methods return deferreds themselves. Something like:
var promises = []; array.forEach(layer.featureSet.features, function (feat) { promises.push(this.geometryService.simplify([feat.geometry])); }, this); all(promises).then(callback, errback);
And the same for areasAndLengths.
This looks confusing to me:
this.geometryService.on('areas-and-lengths-complete', lang.hitch(this, 'showVerifyiedFieldGeometryResults', deferred));
I don't see in the source or docs that hitch takes a 3rd parameter. It looks like you are trying to pass it as a token.
You could rewrite it like this:
this.geometryService.on('areas-and-lengths-complete', this.showVerifyiedFieldGeometryResults(deferred)); //updated showVerifyiedFieldGeometryResults: function(deferred){ return function(results) { var acres = Math.floor(results.result.areas[0]); //NOTE: Check acres to ensure the feature is not too big... code omitted... console.log('geometry results'); //this line always executes so it appears something is wrong with the Deferreds... deferred.resolve('Verified Field Size: ' + acres); } }
I would try that
This code works, but with the same results and problem I am having. This code may be cleaner, but it works the same as using lang.hitch. Thanks.
Jerry Garcia Looks like deferred hell to me. Here's my take on that problem all with 2 sever calls and no deferreds:
constructor: function () { this.geometryService = new GeometryService(this.geometryServiceURL); this.areasAndLengthParams = lang.mixin(new AreasAndLengthsParameters(), { lengthUnit: GeometryService.UNIT_FOOT, areaUnit: GeometryService.UNIT_ACRES, calculationType: 'geodesic' }); }, validate: function (layer) { var geometries = []; array.forEach(layer.featureSet.features, function (feat) { geometries.push(feat.geometry); }); this.geometryService.simplify(geometries, lang.hitch(this, '_simplifyResult'), lang.hitch(this, '_simplifyError')); }, _simplifyResult: function (results) { this.areasAndLengthParams.polygons = results; this.geometryService.areasAndLengths(this.areasAndLengthParams, lang.hitch(this, '_areasAndLengthsResult', results), lang.hitch(this, '_areasAndLengthsError')); }, _simplifyError: function (error) { // handle error }, _areasAndLengthsResult: function (simplifiedGeometries, results) { // i'm making a HUGE assumption here the array of areas is in the same order as geometries passed to areasAndLengths array.forEach(simplifiedGeometries, function (simpGeom, idx) { var acres = Math.floor(result.areas[idx]); // do your check here }, this); }, _areasAndLengthsError: function (error) { // handle error }
Also check out esri/geometry/geometryEngineAsync | API Reference | ArcGIS API for JavaScript . It's all on the client now.
I agree this is a good approach, but I'd like to process one feature at a time. I have additional verification rules I need to process on each feature before adding to the map. I simplified the code for this example. I'm really interested in finding out why the all.then() does not execute when I can see all of the deferreds in the array are resolved()? But, it does execute, when there is only one deferred. Thanks!
I guess I don't understand why you need deferreds when the geom service methods return deferreds themselves. Something like:
var promises = []; array.forEach(layer.featureSet.features, function (feat) { promises.push(this.geometryService.simplify([feat.geometry])); }, this); all(promises).then(callback, errback);
And the same for areasAndLengths.
Thanks. Your suggestion helped me figure it out. Passing a Deferred to the callback like this does not work called multiple times: this.geometryService.on('areas-and-lengths-complete', lang.hitch(this, 'showVerifyiedFieldGeometryResults', deferred)); Instead, this works: geometryService.areasAndLengths(params, function(results){ ... deferred.resolve(); }