Reputation: 3531
I have the following code:
//this 'hitches' the scope to the appropriate callback method
var hitchWidgetToPopulateHierarchyDefinitionFields = DojoBaseLang.hitch(this, populateHierarchyDefinitionFieldsFromSelectedHierarchyTable);
hitchWidgetToPopulateHierarchyDefinitionFields();
function selectValuesByFieldFromHierarchyTable(currentlySelectedColumn) {
//query database and return an array of strings
}
function addHierarchyLevelSelectionToDOM (hierarchyLevelsArray) {
var temporaryDataStore= [];
for (var i=0; i<hierarchyLevelsArray.length;i++){
//DO STUFF
}
}
function populateHierarchyDefinitionFieldsFromSelectedHierarchyTable(){
var selectedHierarchyDefinitionColumn = "COLUMN_NAME"
var p1 = new Promise(function( resolve, reject) {
setTimeout(function() {
resolve(selectValuesByFieldFromHierarchyTable(selectedHierarchyDefinitionColumn))
},2000);
});
p1.then(
function resolve(value) {
console.log(value);
addHierarchyLevelSelectionToDOM(value);
}
).catch(
function reject(error) {
console.error(error);
}
);
}
This results in the console output logging the value but the value is still undefined inside of the addHierarchyLevelSelectionToDOM
:
TypeError: Cannot read property 'length' of undefined
Object {Relevant data }
Notice that the object is indeed logged, and the error is caught inside of the catch.
My intention is simply to call addHierarchyLevelSelectionToDOM
from the value returned by selectValuesByFieldFromHierarchyTable
. The problem is that the value is undefined when addHierarchyLevelSelectionToDOM(value)
is called, but the console.log(value)
call prints the correct returned value. I then tried multiple promises to the same avail:
var p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(selectValuesByFieldFromHierarchyTable(selectedHierarchyDefinitionColumn))
}, 2000);
});
var p2 = p1.then(function(value) {
console.log(value);
return new Promise(addHierarchyLevelSelectionToDOM(value));
});
p2.then(function(value) {
console.log(value);
});
Of course, in this case the second console.log(value)
does not get called due to the resolve addHierarchyLevelSelectionToDOM(value)
failing. I would like to accomplish this goal in pure Javascript if possible.
Any assistance is greatly appreciated!
Upvotes: 2
Views: 96
Reputation: 3531
The problem with the code was inside of selectValuesByFieldFromHierarchyTable
Inside of it was a call to an async function queryFeatures of type Deferred
The solution was to return the deferred (async) type and then the desired data array uniqueHierarchyLevels
function selectValuesByFieldFromHierarchyTable(currentlySelectedColumn) {
//query database and return an array of strings
//now returning the deferred type returned by queryFeatures as well as the array
return hierarchyTableFeatureLayer.queryFeatures(hierarchyTableQuery, function(featureSet){
for (var i = 0; i<featureSet.features.length; i++){
uniqueHierarchyLevels.push(featureSet.features[i])
}
}).then(function afterQuery(){
return uniqueHierarchyLevels;
});
}
function populateHierarchyDefinitionFieldsFromSelectedHierarchyTable(){
var selectedHierarchyDefinitionColumn = "COLUMN_NAME";
deferred.resolve(selectUniqueValuesByFieldFromHierarchyTable(selectedHierarchyDefinitionColumn));
deferred.then(function queryFeaturesAsyncCall(featureSetCallback) {
featureSetCallback.then(
function (hierarchyLevelsArray) {
addHierarchyLevelSelectionToDOM(hierarchyLevelsArray);
},
function (err) {
// Do something when the process errors out
console.log(err);
})
});
}
Upvotes: 0
Reputation: 1719
At least with your first - deleted - question it was likely that you had an error within the Promise constructor, more precisely in selectValuesByFieldFromHierarchyTable
Just do:
var p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve("bla");
}, 2000);
});
p1.then(function(value) {
console.log(value);
});
And suddenly it works. So this is the reason why you also should have a reject function in most cases, because reject() is not only called when you manually reject, but also when an error is thrown - for whatever reason:
p1.then(
function resolve(value) {
console.log(value);
},
function reject(error) {
console.error(error);
}
);
But wait! Now, if you have an error within "resolve" it will silently fail as well. So its even better to use this pattern:
p1.then(
function resolve(value) {
console.log(value);
}
).catch(
function reject(error) {
console.error(error);
}
);
Try again with this and the picture should become more clear.
(Note that the function naming is not mandatory but helps with debugging)
Edit: about "pure Javascript". Well, what do you mean? That is pure Javascript and Promises are a standard as well. Most modern Browsers can do this natively, and for the rest, just use a polyfill that should work perfectly, as Promises can be "emulated" 100%.
Upvotes: 3
Reputation: 3623
Try this:
var p1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(selectValuesByFieldFromHierarchyTable(selectedHierarchyDefinitionColumn.innerHTML))
}, 2000);
});
p1.then(addHierarchyLevelSelectionToDOM);
Upvotes: 1